
H:\PROGRA~2\Gen2>rem This batch file must be invoked from the directory containing the exe to be profiled.  If used from the IDE, do not change directories before running as a custom batch file. 

H:\PROGRA~2\Gen2>rem Line count profiling takes more time than other modes.  See Help about limiting the scope of profiling if profiling a large application. 

H:\PROGRA~2\Gen2>prep /om /lv gen2.exe 

H:\PROGRA~2\Gen2>if errorlevel 1 goto done 

H:\PROGRA~2\Gen2>profile gen2         

H:\PROGRA~2\Gen2>if errorlevel 1 goto done 

H:\PROGRA~2\Gen2>prep /m gen2 

H:\PROGRA~2\Gen2>if errorlevel 1 goto done 

H:\PROGRA~2\Gen2>plist gen2 
Profile: Line coverage, sorted by line
Date:    Wed Jun 23 22:34:27 1999


Program Statistics
------------------
    Command line at 1999 Jun 23 22:33: gen2        
    Total lines: 4045
    Line coverage: 74.0%

Module Statistics for gen2.exe
------------------------------
    Lines in module: 4045
    Module line coverage: 74.0%


Source file: h:\programming\gen2\game.cpp

  Line Covered  Source
----------------------
    1:          #include "physics.cpp"
    2:          #include <fstream.h>
    3:          #include <math.h>
    4:          
    5:          #define pi 3.1415926535
    6:          
    7:          BITMAP *buf;
    8:          BITMAP *bg;
    9:          BITMAP *sky;
   10:          BITMAP *ground;
   11:          BITMAP *mousebmp;
   12:          BITMAP *scorch;
   13:          BITMAP *explosionanim[16];
   14:          BITMAP *explosionsmallanim[24];
   15:          BITMAP *smokeanim[24];
   16:          BITMAP *redanim[24];
   17:          BITMAP *yellowanim[24];
   18:          BITMAP *whiteanim[24];
   19:          BITMAP *splashanim[6];
   20:          BITMAP *tankbarrelanim[10];
   21:          BITMAP *exptemp;
   22:          BITMAP *bombbmp;
   23:          BITMAP *shell;
   24:          BITMAP *debrisr[4];
   25:          BITMAP *debrisrm[4];
   26:          BITMAP *debris1;
   27:          BITMAP *debriso1;
   28:          BITMAP *grounddebris1;
   29:          FILE *debug;
   30:          
   31:          MIDI *music;
   32:          SAMPLE *mgun;
   33:          SAMPLE *explode;
   34:          SAMPLE *explodesmall;
   35:          SAMPLE *engine;
   36:          SAMPLE *prop;
   37:          SAMPLE *enginestart;
   38:          SAMPLE *propstart;
   39:          SAMPLE *death1;
   40:          SAMPLE *bombdrop;
   41:          SAMPLE *aagunfire;
   42:          SAMPLE *tankfire;
   43:          SAMPLE *gurgle;
   44:          SAMPLE *splash;
   45:          
   46:          atom *center;
   47:          
   48:          int path[4000];
   49:          int debrislev[4000];
   50:          
   51:          extern int magenta;
   52:          int mx, my, slx;
   53:          
   54:          float convk;
   55:          float convk2;
   56:          float lx, rx;
   57:          int numsplashes;
   58:          
   59:          extern int COMPFRAMES;
   60:          
   61:          extern atom *structure[100][100];
   62:          
   63:          #define LEFT 0
   64:          #define RIGHT 1
   65:          #define MAXBULLETS 100
   66:          #define MAXBOMBS 10
   67:          #define MAXSOLDIERS 50
   68:          #define MAXCOMPSOLDIERS 50
   69:          #define MAXANIMATIONS 1000
   70:          #define MAXTRAILANIMS 300
   71:          #define MAXAAGUNS 10
   72:          #define MAXJEEPS 10
   73:          #define MAXPLANES 10
   74:          #define MAXTANKS 10
   75:          
   76:          #define WINDOWED 0
   77:          
   78:          bool tmplevels[MAXLEVELS];
   79:          
   80:          int level;
   81:          int frame;
   82:          int drawframe;
   83:          int waterlevel;
   84:          
   85:          bool dispframe;
   86:          
   87:          int screencenterx;          //Center of window / screen
   88:          int pan;
   89:          int vol;
   90:          
   91:          /*      **LEVELS**
   92:          
   93:            0: Nothing interacts with this. Used for debris
   94:            1: The human player
   95:            2: The upper part of buildings (that the player cannot walk through)
   96:            3: The human's bullets
   97:            4: The lower part of buildings (that the player can walk through)
   98:            5: Enemy soldiers
   99:            6: Enemy bullets
  100:            7: Empty vehicles
  101:            8: Corpses
  102:            9: Acts like bullets (bomb bullets)
  103:            10: Personnel bullets
  104:            11: Friendly controlled vehicles
  105:            12: Enemy controlled vehicles
  106:            13: Friendly bombs
  107:            14: Enemy bombs
  108:           
  109:          */
  110:          
  111:    .     void dopan(float x) {
  112:    .         pan = (x - screencenterx) * 0.2 + 128;
  113:    .         if(pan > 255) pan = 255;
  114:    .         if(pan < 0) pan = 0;
  115:    .     }
  116:          
  117:    .     void dovol(float x, float k) {
  118:    .         vol = 255 - abs(x - screencenterx) * k;
  119:    .         if(vol < 0) vol = 0;
  120:    .     }
  121:          
  122:    *     void dopanvol(float x, float k) {
  123:    *         pan = (x - screencenterx) * 0.2 + 128;
  124:    *         if(pan > 255) pan = 255;
  125:    *         if(pan < 0) pan = 0;
  126:    *         vol = 255 - abs(x - screencenterx) * k;
  127:    *         if(vol < 0) vol = 0;
  128:              //fprintf(debug, "screenx = %i, x = %f, k = %f, vol = %i\n", screencenterx, x, k, vol);
  129:    *     }
  130:          
  131:    *     void settmplevels() {
  132:              int i;  
  133:    *         for(i = 1; i < MAXLEVELS; i++) {
  134:    *             tmplevels[i] = true;
  135:    *         }
  136:    *         tmplevels[0] = false;
  137:    *         tmplevels[8] = false;
  138:    *         tmplevels[10] = false;
  139:    *     }
  140:          
  141:    *     void cleartmplevels() {
  142:              int i;  
  143:    *         for(i = 0; i < MAXLEVELS; i++) {
  144:    *             tmplevels[i] = false;
  145:    *         }
  146:    *     }
  147:          
  148:    *     void adddebris(atom *a, bool accrue) {
  149:              //destroyatom(a);
  150:              //return;
  151:    *         if(a->fixed) return;
  152:              debrisitem *d;
  153:              int i;
  154:          
  155:    *         d = &(debris[0]);
  156:    *         for(i = 0; i < MAXDEBRIS; i++) {
  157:    *             if(!d->on) {
  158:    *                 d->me = a;
  159:    *                 d->on = true;
  160:    *                 d->me->debris = true;
  161:    *                 d->me->level = 0;
  162:    *                 d->me->d = d;
  163:    *                 d->accrue = accrue;
  164:    *                 for(i = 0; i < MAXLEVELS; i++) {
  165:    *                     d->me->levels[i] = false;
  166:    *                 }
  167:    *                 break;
  168:                  }
  169:    *             d++;
  170:    *         }
  171:    *     }
  172:          
  173:          struct bullet {
  174:              atom *me;
  175:              int life;
  176:              bool drew;
  177:              bool todraw;
  178:              int width;
  179:              int color;
  180:          
  181:    *         bullet() {
  182:    *             init();
  183:    *         }
  184:          
  185:    *         void init() {
  186:    *             me = NULL;
  187:    *             life = -1;
  188:    *             drew = false;
  189:    *             todraw = true;
  190:    *             width = 1;
  191:    *             color = black;
  192:    *         }
  193:          
  194:    *         void update() {
  195:    *             if(me == NULL) return;
  196:    *             me->iy -= GRAVITY;
  197:    *             life--;
  198:                  //if(life < 1000 && change > 1.5 || (abs((int)me->ix) < .1 && abs((int)me->iy) < .1)) life = 0;
  199:    *             if((fabs(me->ix) * me->rmdt < .5 && fabs(me->iy) * me->rmdt < .5)) life = 0;
  200:    *             if(life <= 0) {
  201:    *                 destroyatom(me);
  202:    *                 me = NULL;
  203:    *                 life = -1;
  204:                  }
  205:    *         }
  206:          
  207:    *         void draw() {
  208:    *             if(!todraw || color == -1) return;
  209:          
  210:    *             if(width != 1) {
  211:                      int points[8];
  212:                      int p1x, p2x, p1y, p2y;
  213:    .                 float m = -me->ix / me->iy;
  214:                      float ox, oy, od;
  215:    .                 ox = 1; oy = m;
  216:    .                 od = sqrt(ox * ox + oy * oy);
  217:    .                 ox = ox / od;
  218:    .                 oy = oy / od;
  219:    .                 ox *= width * 0.5;
  220:    .                 oy *= width * 0.5;
  221:    .                 p1x = me->x;
  222:    .                 p1y = me->y;
  223:    .                 p2x = p1x - me->ix * 10 * me->rmdt;
  224:    .                 p2y = p1y - me->iy * 10 * me->rmdt;
  225:                      
  226:    .                 points[0] = p1x - ox;
  227:    .                 points[1] = p1y - oy;
  228:    .                 points[2] = p1x + ox;
  229:    .                 points[3] = p1y + oy;
  230:    .                 points[4] = p2x + ox;
  231:    .                 points[5] = p2y + oy;
  232:    .                 points[6] = p2x - ox;
  233:    .                 points[7] = p2y - oy;
  234:          
  235:    .                 polygon(buf, 4, points, color);
  236:    .                 line(buf, points[0], points[1], points[2], points[3], black);
  237:    .                 line(buf, points[2], points[3], points[4], points[5], black);
  238:    .                 line(buf, points[4], points[5], points[6], points[7], black);
  239:    .                 line(buf, points[6], points[7], points[0], points[1], black);
  240:    .                 drew = true;
  241:                  }
  242:    .             else {
  243:                      //float m = me->iy / me->ix;
  244:                      int p1x, p2x, p1y, p2y;
  245:    *                 p1x = me->x;
  246:    *                 p1y = me->y;
  247:    *                 p2x = p1x - me->ix * 2;
  248:    *                 p2y = p1y - me->iy * 2;
  249:    *                 if((p1x > lx && p1x < rx) || (p2x > lx && p2x < rx)) {
  250:    *                     line(buf, p1x, p1y, p2x, p2y, color);
  251:    *                     drew = true;
  252:                      }
  253:                  }
  254:    *         }
  255:          
  256:    *         void erase() {
  257:    *             if(!todraw) return;
  258:    *             if(width == 1) {
  259:                      //float m = me->iy / me->ix;
  260:    *                 if(!drew) return;
  261:                      int p1x, p2x, p1y, p2y;
  262:    *                 p1x = me->x;
  263:    *                 p1y = me->y;
  264:    *                 p2x = p1x - me->ix * 2;
  265:    *                 p2y = p1y - me->iy * 2;
  266:    *                 do_line(buf, p1x, p1y, p2x, p2y, 0, cleanline);
  267:    *                 drew = false;
  268:                  }
  269:    *             else {
  270:                      int p1x, p2x, p1y, p2y, nx, ny, nw, nh;
  271:    .                 p1x = me->x;
  272:    .                 p1y = me->y;
  273:    .                 p2x = p1x - me->ix * 4;
  274:    .                 p2y = p1y - me->iy * 4;
  275:    .                 nx = findlow(p1x, p2x) - 2 * width;
  276:    .                 ny = findlow(p1y, p2y) - 2 * width;
  277:    .                 nw = findhigh(p1x, p2x) - nx + 4 * width;
  278:    .                 nh = findhigh(p1y, p2y) - ny + 4 * width;
  279:    .                 blit(bg, buf, nx, ny, nx, ny, nw, nh);
  280:                  }           
  281:    *         }
  282:          };
  283:          
  284:    *     bullet bullets[MAXBULLETS];
  285:          
  286:          bullet *addbullet(float, float, float, float, int, int, float, int, int, bool);
  287:          
  288:          void addanimation(BITMAP **newframes, int newnumframes, int newx, int newy, bool trans, float dy, int delay, int rand);
  289:          
  290:          struct bomb {
  291:              atom *me;
  292:              BITMAP *bmp;
  293:              bool drew;
  294:              bool on;
  295:          
  296:    *         bomb() {
  297:    *             init();
  298:    *         }
  299:          
  300:    *         void init() {
  301:    *             me = NULL;
  302:    *             drew = false;
  303:    *             on = false;
  304:    *         }
  305:          
  306:    *         void update() {
  307:    *             if(!on) return;
  308:                  float cx, cy, cd;
  309:    *             cx = me->ix - me->oix;
  310:    *             cy = me->iy - me->oiy;
  311:          
  312:    *             cy -= GRAVITY;
  313:    *             cd = sqrt(cx * cx + cy * cy);
  314:    *             cd = fabs(cd);
  315:                  
  316:    *             if(cd > 0.05) {
  317:                      bullet *b;
  318:    *                 on = false;
  319:    *                 float ang = 0;
  320:                      int py;
  321:                      float ca, sa;
  322:                      atom *a;
  323:    *                 int count = 0;
  324:          
  325:    *                 py = path[(int)me->x];
  326:          
  327:    *                 for(ang = 0; ang < 2*pi; ang += (2*pi) / 10) {
  328:    *                     count++;
  329:    *                     ca = cos(ang);
  330:    *                     sa = sin(ang);
  331:    *                     b = addbullet(me->x, me->y, 20 * ca, 20 * sa, 3, 10, 20, 1, gray, false);
  332:    *                     if(b && b->me) {
  333:    *                         b->me->dmult = 100;
  334:                          }
  335:    *                     b = addbullet(me->x, me->y, 20 * ca, 20 * sa, 3, 50, 20, 1, -1, true);
  336:    *                     if(b && b->me) {
  337:    *                         b->me->dmult = 100;
  338:                          }
  339:    *                     if(me->y > py - 20) {
  340:    *                         cleartmplevels();
  341:    *                         a = addatom(me->x, py - 15, tmplevels, 0);
  342:    *                         a->ix = (rand() % 10 / 10.0) * ca;
  343:    *                         a->iy = (rand() % 10 / 10.0) * sa;
  344:    *                         a->bmp = create_bitmap(14, 14);
  345:    *                         blit(grounddebris1, a->bmp, 0, 0, 0, 0, 14, 14);
  346:    *                         adddebris(a, false);
  347:                          }
  348:    *                     if(count % 1 == 0) {
  349:    *                         tmplevels[1] = true;
  350:    *                         tmplevels[5] = true;
  351:    *                         a = addatom(me->x, me->y, tmplevels, 10);
  352:                              //a->ix = (rand() % 10 / 3.0) * ca;
  353:                              //a->iy = (rand() % 10 / 3.0) * sa;
  354:    *                         a->ix = 1.5 * ca;
  355:    *                         a->iy = 1.5 * sa;
  356:    *                         a->life = 40;
  357:    *                         a->draw = true;
  358:    *                         a->color = magenta;
  359:                              //a->bmp = create_bitmap(14, 14);
  360:          //void addtrailanim(atom *a, BITMAP **anim, int frames, int mod, int modoff, int life, float dy, int rand, bool trans, int delay);
  361:    *                         addtrailanim(a, explosionsmallanim, 24, 5, 0, 100, -2, 5, false, -3);
  362:                              //blit(bombdebris1, a->bmp, 0, 0, 0, 0, 14, 14);
  363:    *                         adddebris(a, false);
  364:                          }
  365:    *                 }
  366:    *                 addanimation(explosionanim, 16, me->x - 32, me->y - 37, true, 0, 1, 0);
  367:    *                 dopanvol(me->x, 0.1);
  368:    *                 play_sample(explode, vol, pan, 1000, 0);
  369:          
  370:    *                 if(me->y > py - 5) {                
  371:                          BITMAP *tmp;
  372:                          int py, pyr, nx;
  373:    *                     tmp = create_bitmap(60, 60);
  374:    *                     blit(bg, tmp, me->x - 27, me->y - 19, 0, 0, 60, 60);
  375:    *                     draw_trans_sprite(tmp, scorch, 0, 0);
  376:    *                     for(int xp = 0; xp < 60; xp++) {
  377:    *                         nx = (int)xp + (int)me->x - 27;
  378:    *                         if(nx > 0 && nx < buf->w - 1) {
  379:    *                             py = path[(int)xp + (int)me->x - 27] + 1;
  380:    *                             pyr = py - me->y + 20 + 1;
  381:    *                             blit(tmp, bg, xp, pyr, xp + me->x - 27, py, 1, 60 - pyr);
  382:    *                             blit(tmp, buf, xp, pyr, xp + me->x - 27, py, 1, 60 - pyr);
  383:                              }
  384:                              //blit(tmp, buf, xp, 0, xp + a->x - 27, a->y - 20, 1, path[(int)xp] - (a->y - 22));
  385:    *                     }
  386:    *                     destroy_bitmap(tmp);
  387:    *                     tmp = NULL;
  388:                      }
  389:          
  390:    *                 destroyatom(me);
  391:    *                 me = NULL;
  392:                  }
  393:    *         }
  394:          
  395:    *         void draw() {
  396:    *             if(!on) return;
  397:    *             if(me->x + 5 > lx && me->x - 5 < rx) {
  398:                      float angle;
  399:    *                 angle = atan2(me->iy, me->ix);
  400:    *                 angle *= convk;
  401:    *                 rotate_sprite(buf, bmp, me->x - 5, me->y - 2, itofix(angle));
  402:    *                 drew = true;
  403:                  }
  404:    *         }
  405:          
  406:    *         void erase() {
  407:    *             if(!on) return;
  408:    *             if(!drew) return;
  409:    *             drew = false;
  410:    *             blit(bg, buf, me->x - 8, me->y - 8, me->x - 8, me->y - 8, 16, 16);
  411:    *         }
  412:          };
  413:          
  414:    *     bomb bombs[MAXBOMBS];
  415:          int numbombs;
  416:          
  417:    *     bullet *addbullet(float x, float y, float ix, float iy, int comp, int life, float dmult, int width, int color, bool personnel) {
  418:              bullet *b;
  419:              int i;
  420:              int level;
  421:          
  422:    *         settmplevels();
  423:    *         if(personnel) {
  424:    *             cleartmplevels();
  425:    *             tmplevels[1] = true;
  426:    *             tmplevels[5] = true;
  427:    *             tmplevels[13] = false;
  428:    *             tmplevels[14] = false;
  429:    *             level = 10;
  430:              }
  431:    *         else if(comp == 0) {
  432:    *             tmplevels[1] = false;
  433:    *             tmplevels[3] = false;
  434:    *             tmplevels[6] = false;
  435:    *             tmplevels[7] = false;
  436:    *             tmplevels[9] = false;
  437:    *             tmplevels[13] = false;
  438:    *             tmplevels[14] = false;
  439:    *             level = 3;
  440:              }
  441:    *         else if(comp == 1) {
  442:    .             tmplevels[2] = false;
  443:    .             tmplevels[3] = false;
  444:    .             tmplevels[4] = false;
  445:    .             tmplevels[5] = false;
  446:    .             tmplevels[6] = false;
  447:    .             tmplevels[9] = false;
  448:    .             tmplevels[13] = false;
  449:    .             tmplevels[14] = false;
  450:    .             level = 6;
  451:              }
  452:    .         else if(comp == 3) {
  453:    *             tmplevels[9] = false;
  454:    *             tmplevels[13] = false;
  455:    *             tmplevels[14] = false;
  456:    *             level = 9;
  457:              }
  458:          
  459:    *         b = &(bullets[0]);
  460:    *         for(i = 0; i < MAXBULLETS; i++) {
  461:    *             if(b->life < 0) {
  462:    *                 b->life = life;
  463:    *                 b->me = addatom(x, y, tmplevels, level);
  464:    *                 b->me->ix = ix;
  465:    *                 b->me->iy = iy;
  466:    *                 b->me->dmult = dmult;
  467:    *                 b->width = width;
  468:    *                 b->todraw = true;
  469:    *                 b->color = color;
  470:    *                 if(comp != 3) {
  471:    *                     b->me->rmdt = 1;
  472:                      }
  473:    *                 else {
  474:    *                     b->todraw = false;
  475:    *                     b->me->rmdt = 0.1;
  476:                      }
  477:    *                 return b;
  478:                      break;
  479:                  }
  480:    *             b++;
  481:    *         }
  482:    .         return NULL;
  483:    *     }
  484:          
  485:    *     void addbomb(float x, float y, float ix, float iy, bool comp, BITMAP *bmp) {
  486:              bomb *b;
  487:              int level;
  488:              int i;
  489:          
  490:    *         settmplevels();
  491:    *         if(!comp) {
  492:    *             tmplevels[1] = false;
  493:    *             tmplevels[3] = false;
  494:    *             tmplevels[6] = false;
  495:    *             tmplevels[7] = false;
  496:    *             tmplevels[9] = false;
  497:    *             tmplevels[10] = false;
  498:    *             tmplevels[11] = false;
  499:    *             tmplevels[13] = false;
  500:    *             tmplevels[14] = false;
  501:    *             level = 13;
  502:              }
  503:    *         else {
  504:    *             tmplevels[2] = false;
  505:    *             tmplevels[3] = false;
  506:    *             tmplevels[4] = false;
  507:    *             tmplevels[5] = false;
  508:    *             tmplevels[6] = false;
  509:    *             tmplevels[7] = false;
  510:    *             tmplevels[9] = false;
  511:    *             tmplevels[10] = false;
  512:    *             tmplevels[12] = false;
  513:    *             tmplevels[13] = false;
  514:    *             tmplevels[14] = false;
  515:    *             level = 14;
  516:              }
  517:          
  518:    *         b = &(bombs[0]);
  519:    *         i = 0;
  520:    *         while(i < MAXBOMBS && b->on) {b++; i++;}
  521:    *         if(i >= MAXBOMBS) return;
  522:    *         b->on = true;
  523:    *         b->me = addatom(x, y, tmplevels, level);
  524:    *         b->me->ix = ix;
  525:    *         b->me->iy = iy;
  526:    *         b->me->oix = ix;
  527:    *         b->me->oiy = iy + GRAVITY;
  528:    *         b->me->rmdt = 1;
  529:    *         b->bmp = bmp;
  530:    *         if(b == &(bombs[numbombs]))
  531:    *             numbombs++;
  532:    *     }
  533:          
  534:          typedef struct soldier soldier;
  535:          
  536:          struct animation {
  537:              BITMAP **frames;
  538:              int aframe;
  539:              int numframes;
  540:              float x, y;
  541:              bool on;
  542:              bool drew;
  543:              bool trans;
  544:              int w, h;
  545:              float dy;
  546:              int delay;
  547:              int randoff;
  548:          
  549:    *         animation() {
  550:    *             reset();
  551:    *         }
  552:          
  553:    *         void reset() {
  554:    *             aframe = 0;
  555:    *             on = false;
  556:    *             trans = false;
  557:    *             delay = 1;
  558:    *         }
  559:          
  560:    *         void init(BITMAP **newframes, int newnumframes, int newx, int newy, float newdy, int newdelay, int newrand) {
  561:    *             frames = newframes;
  562:    *             numframes = newnumframes;
  563:    *             aframe = 0;
  564:    *             x = newx;
  565:    *             y = newy;
  566:    *             w = frames[0]->w;
  567:    *             h = frames[0]->h;
  568:    *             on = true;
  569:    *             dy = newdy;
  570:    *             delay = newdelay;
  571:    *             randoff = newrand;
  572:    *         }
  573:          
  574:    *         void draw() {
  575:    *             if(!on) return;
  576:    *             if(aframe == numframes) {
  577:    *                 on = false;
  578:                  }
  579:    *             else if(x + w > lx && x < rx) {
  580:    *                 drew = true;
  581:    *                 y += dy;
  582:    *                 if(dy != 0) {
  583:    *                     x += rand() % randoff * 0.1 - 0.05 * randoff;
  584:    *                     y += rand() % randoff * 0.1 - 0.05 * randoff;
  585:                      }
  586:    *                 if(trans) draw_trans_sprite(buf, frames[aframe], x, y);
  587:    *                 else draw_sprite(buf, frames[aframe], x, y);
  588:    *                 if(delay < 0) {
  589:    *                     aframe += -delay;
  590:    *                     if(aframe > numframes) aframe = numframes;
  591:                      }
  592:    *                 else if(delay == 1 || drawframe % delay == 0) {
  593:    *                     aframe++;
  594:                      }
  595:                  }
  596:    *             else if(delay == 1 || drawframe % delay == 0) {
  597:    *                 y += dy;
  598:    *                 aframe++;
  599:                  }
  600:    *         }
  601:          
  602:    *         void erase() {
  603:    *             if(!on || !drew) return;
  604:    *             blit(bg, buf, x, y, x, y, w, h);
  605:    *             drew = false;
  606:    *         }
  607:          };
  608:          
  609:    *     animation animations[MAXANIMATIONS];
  610:          int numanimations;
  611:          
  612:    *     void addanimation(BITMAP **newframes, int newnumframes, int newx, int newy, bool trans, float dy, int delay, int rand) {
  613:              animation *a;
  614:              int i;
  615:    *         a = &(animations[0]);
  616:    *         i = 0;
  617:    *         while(i < MAXANIMATIONS && a->on) {a++; i++;}
  618:    *         if(i >= MAXANIMATIONS) return;
  619:    *         a->init(newframes, newnumframes, newx, newy, dy, delay, rand);
  620:    *         a->trans = trans;
  621:    *         if(a == &(animations[numanimations]))
  622:    *             numanimations++;
  623:    *     }
  624:          
  625:    *     void drawanimations() {
  626:              animation *a;
  627:              int i;
  628:          
  629:    *         a = &(animations[0]);
  630:    *         for(i = 0; i < numanimations; i++) {
  631:    *             a->draw();
  632:    *             a++;
  633:    *         }
  634:    *     }
  635:          
  636:    *     void eraseanimations() {
  637:              animation *a;
  638:              int i;
  639:          
  640:    *         a = &(animations[0]);
  641:    *         for(i = 0; i < numanimations; i++) {
  642:    *             a->erase();
  643:    *             a++;
  644:    *         }
  645:    *     }
  646:          
  647:          struct trailanim {
  648:              int life;
  649:              atom *me;
  650:              int mod;
  651:              int modoff;
  652:              BITMAP **anim;
  653:              int animframes;
  654:              float dy;
  655:              int randoff;
  656:              bool trans;
  657:              int wot, hot;
  658:              int delay;
  659:          
  660:    *         trailanim() {
  661:    *             reset();
  662:    *         }
  663:              
  664:    *         void reset() {
  665:    *             life = 0;
  666:    *             me = NULL;
  667:    *             mod = 100;
  668:    *             modoff = 0;
  669:    *             anim = NULL;
  670:    *             animframes = 0;
  671:    *             trans = false;
  672:    *             wot = 0;
  673:    *             hot = 0;
  674:    *         }
  675:          
  676:    *         void init(atom *newme, BITMAP **newanim, int newanimframes, int newmod, int newmodoff, int newlife, float newdy, int newrandoff, bool newtrans, int newdelay) {
  677:    *             me = newme;
  678:    *             anim = newanim;
  679:    *             animframes = newanimframes;
  680:    *             mod = newmod;
  681:    *             modoff = newmodoff;
  682:    *             life = newlife;
  683:    *             dy = newdy;
  684:    *             randoff = newrandoff;
  685:    *             trans = newtrans;
  686:    *             wot = (newanim[0])->w * 0.5;
  687:    *             hot = (newanim[0])->h * 0.5;
  688:    *             delay = newdelay;
  689:    *         }
  690:          
  691:    *         void update() {
  692:    *             if(life <= 0) return;
  693:    *             life--;
  694:    *             if(me->on == false)
  695:    *                 life = 0;
  696:    *             else {
  697:    *                 if((frame + modoff) % mod == 0) {
  698:                          
  699:                          //init(BITMAP **newframes, int newnumframes, int newx, int newy, float newdy, int newdelay, int newrand) {
  700:    *                     addanimation(anim, animframes, me->x + rand() % (2 * randoff) - randoff - wot, me->y + rand() % (2 * randoff) - randoff - hot, trans, dy, delay, 1);
  701:                      }
  702:                  }
  703:    *         }
  704:          };
  705:          
  706:    *     trailanim trailanims[MAXTRAILANIMS];
  707:          int numtrailanims;
  708:          
  709:    *     void addtrailanim(atom *a, BITMAP **anim, int frames, int mod, int modoff, int life, float dy, int rand, bool trans, int delay) {
  710:              trailanim *t;
  711:              int i;
  712:    *         t = &(trailanims[0]);
  713:    *         i = 0;
  714:    *         while(i < MAXTRAILANIMS && t->life > 0) {i++; t++;}
  715:    *         if(i < MAXTRAILANIMS) {
  716:    *             t->init(a, anim, frames, mod, modoff, life, dy, rand, trans, delay);
  717:    *             if(t == &(trailanims[numtrailanims]))
  718:    *                 numtrailanims++;
  719:              }
  720:    *     }
  721:          
  722:    *     void updatetrailanims() {
  723:              trailanim *a;
  724:              int i;
  725:          
  726:    *         a = &(trailanims[0]);
  727:    *         for(i = 0; i < numtrailanims; i++) {
  728:    *             a->update();
  729:    *             a++;
  730:    *         }
  731:    *     }
  732:          
  733:          struct aagun {
  734:              BITMAP *hold;
  735:              BITMAP *barrel;
  736:              BITMAP *base;
  737:              BITMAP *baseo;
  738:              BITMAP *baseoe;
  739:              BITMAP *gunbg;
  740:              float angle;
  741:              float fangle;
  742:              float dangle;
  743:              float x, y;
  744:              int offx, offy;
  745:              int w, h;
  746:              float speed;
  747:              bool direction;
  748:              bool occupied;
  749:              bool destroyed;
  750:              soldier *driver;
  751:              int fired;
  752:              float bulletforce;
  753:              int numfired;
  754:              bool drew;
  755:          
  756:              bool *fire;
  757:              float tx, ty;
  758:          
  759:    *         aagun() {
  760:    *             hold = NULL;
  761:    *             reset();
  762:    *         }
  763:          
  764:    *         void reset() {
  765:    *             angle = 192;
  766:    *             fangle = 192;
  767:    *             dangle = 0;
  768:    *             speed = 0.1;
  769:    *             direction = RIGHT;
  770:    *             occupied = false;
  771:    *             destroyed = false;
  772:    *             tx = ty = 0;
  773:    *             fired = 0;
  774:    *             bulletforce = 15;
  775:    *             numfired = 0;
  776:    *             if(hold != NULL) clear_to_color(hold, magenta);
  777:    *             drew = false;
  778:    *         }
  779:          
  780:          
  781:    .         void init(float nx, float ny) {
  782:    .             x = nx;
  783:    .             y = ny;
  784:    .             offx = 8;
  785:    .             offy = 26;
  786:    .             w = 63;
  787:    .             h = 43;
  788:    .             hold = create_bitmap(w, h);
  789:    .             clear_to_color(hold, magenta);
  790:    .             tx = x + 10;
  791:    .             ty = y;
  792:    .         }
  793:          
  794:    .         void getin(soldier *newdriver) {
  795:    .             driver = newdriver;
  796:    .             if(destroyed) return;
  797:    .             if(occupied == false) {
  798:    .                 occupied = true;
  799:                  }
  800:    .             else {
  801:    .                 occupied = false;
  802:                  }
  803:    .         }
  804:          
  805:              void update();
  806:          
  807:              void draw();
  808:          
  809:    .         void erase() {
  810:    .             if(!drew) return;
  811:    .             blit(bg, buf, x, y, x, y, w, h);
  812:    .             drew = false;
  813:    .         }
  814:          };
  815:          
  816:    *     aagun aaguns[MAXAAGUNS];
  817:          int numaaguns;
  818:          
  819:    .     aagun *addaagun(float x, float y) {
  820:              aagun *a;
  821:    .         a = &(aaguns[numaaguns]);
  822:    .         numaaguns++;
  823:    .         a->init(x, y);
  824:    .         return a;
  825:    .     }
  826:          
  827:    *     void drawaaguns() {
  828:              aagun *a;
  829:              int i;
  830:    *         a = &(aaguns[0]);
  831:    *         for(i = 0; i < numaaguns; i++) {
  832:    .             a->draw();
  833:    .             a++;
  834:    .         }
  835:    *     }
  836:          
  837:    *     void updateaaguns() {
  838:              aagun *a;
  839:              int i;
  840:    *         a = &(aaguns[0]);
  841:    *         for(i = 0; i < numaaguns; i++) {
  842:    .             a->update();
  843:    .             a++;
  844:    .         }
  845:    *     }   
  846:          
  847:    *     void eraseaaguns() {
  848:              aagun *a;
  849:              int i;
  850:    *         a = &(aaguns[0]);
  851:    *         for(i = 0; i < numaaguns; i++) {
  852:    .             a->erase();
  853:    .             a++;
  854:    .         }
  855:    *     }
  856:          
  857:          struct jeep {
  858:              rigidbody *me;
  859:              bool occupied;
  860:              float strength;
  861:              object *myobj;
  862:              BITMAP *unoc;
  863:              BITMAP *unocl;
  864:              BITMAP *occ;
  865:              BITMAP *occl;
  866:              BITMAP *exp;
  867:              BITMAP *expl;
  868:              float damage;
  869:              soldier *driver;
  870:          
  871:              volatile char *keyleft;
  872:              volatile char *keyright;
  873:              volatile char *keyup;
  874:              volatile char *keydown;
  875:          
  876:              bool direction;
  877:              int engvoice;
  878:              int engstartvoice;
  879:              bool engstarted;
  880:              bool destroyed;
  881:              bool on;
  882:          
  883:    *         jeep() {
  884:    *             reset();
  885:    *         }
  886:          
  887:    *         void reset() {
  888:    *             occupied = false;
  889:                  //strength = 0.06;
  890:    *             strength = 0.1;
  891:    *             keyleft = &(key[KEY_A]);
  892:    *             keyright = &(key[KEY_D]);
  893:    *             keyup = &(key[KEY_W]);
  894:    *             keydown = &(key[KEY_S]);
  895:    *             direction = RIGHT;
  896:    *             destroyed = false;
  897:    *             damage = 0;
  898:    *             driver = NULL;
  899:    *             on = false;
  900:    *         }
  901:          
  902:    *         void init() {
  903:    *             dovoices();
  904:    *         }
  905:          
  906:    *         void killvoices() {
  907:    *             if(engvoice != NULL) deallocate_voice(engvoice);
  908:    *             engvoice = NULL;
  909:    *             if(engstartvoice != NULL) deallocate_voice(engstartvoice);
  910:    *             engstartvoice = NULL;
  911:    *         }
  912:          
  913:    *         void dovoices() {
  914:    *             if(engvoice != NULL) deallocate_voice(engvoice);
  915:    *             engvoice = allocate_voice(engine);
  916:    *             voice_set_playmode(engvoice, PLAYMODE_LOOP);
  917:    *             voice_start(engvoice);
  918:    *             voice_set_volume(engvoice, 0);
  919:    *             voice_set_priority(engvoice, 255);
  920:    *             if(engstartvoice != NULL) deallocate_voice(engstartvoice);
  921:    *             engstartvoice = allocate_voice(enginestart);
  922:    *             voice_stop(engstartvoice);
  923:    *         }
  924:          
  925:    .         void getin(soldier *newdriver) {
  926:    .             driver = newdriver;
  927:    .             if(destroyed) return;
  928:    .             if(occupied == false) {
  929:    .                 occupied = true;
  930:    .                 if(voice_check(engstartvoice) != enginestart) dovoices();
  931:    .                 voice_start(engstartvoice);
  932:    .                 dopanvol(me->x, 0.5);
  933:    .                 voice_set_pan(engstartvoice, pan);
  934:    .                 voice_set_volume(engstartvoice, vol);
  935:    .                 release_voice(engstartvoice);
  936:    .                 engstarted = false;
  937:    .                 voice_set_position(engstartvoice, 0);
  938:                      //voice_ramp_volume(engvoice, 100, 255);
  939:    .                 if(direction == RIGHT)
  940:    .                     myobj->obj = occ;
  941:    .                 else
  942:    .                     myobj->obj = occl;
  943:                  }
  944:    .             else {
  945:    .                 voice_ramp_volume(engvoice, 100, 0);
  946:    .                 occupied = false;
  947:    .                 engstarted = false;
  948:    .                 if(direction == RIGHT)
  949:    .                     myobj->obj = unoc;
  950:    .                 else
  951:    .                     myobj->obj = unocl;
  952:                  }
  953:    .         }
  954:          
  955:    .         void dokeys() {
  956:    .             if(destroyed) return;
  957:                  float appstrength;
  958:                  float dx, dy, d;
  959:          
  960:    .             if(!engstarted && voice_get_position(engstartvoice) >= 10000) {
  961:    .                 voice_ramp_volume(engvoice, 100, 255);
  962:    .                 engstarted = true;
  963:                  }
  964:          
  965:    .             dx = me->atomlist[3]->x - me->atomlist[0]->x;
  966:    .             dy = me->atomlist[3]->y - me->atomlist[0]->y;
  967:    .             d = sqrt(dx * dx + dy * dy);
  968:    .             dx = dx / d;
  969:    .             dy = dy / d;
  970:          
  971:    .             appstrength = strength * COMPFRAMES;
  972:          
  973:    .             dx *= appstrength;
  974:    .             dy *= appstrength;      
  975:          
  976:    .             if(me->y > path[(int)me->x] - 20) {
  977:          
  978:                      /*
  979:                      if(*keydown && !*keyup) {
  980:                          if(direction == RIGHT) {
  981:                              me->ix -= dx;
  982:                              me->iy -= dy;
  983:                          }
  984:                          else {
  985:                              me->ix += dx;
  986:                              me->iy += dy;
  987:                          }
  988:                      }
  989:                      else if(*keyup && !*keydown) {
  990:                          if(direction == LEFT) {
  991:                              me->ix -= dx;
  992:                              me->iy -= dy;
  993:                          }
  994:                          else {
  995:                              me->ix += dx;
  996:                              me->iy += dy;
  997:                          }
  998:                      }
  999:                      */
 1000:    .                 if(*keyleft && !*keyright && !*keydown) {
 1001:    .                     me->ix -= dx;
 1002:    .                     me->iy -= dy;
 1003:    .                     if(direction != LEFT) {
 1004:    .                         direction = LEFT;
 1005:    .                         myobj->obj = occl;
 1006:                          }
 1007:                      }
 1008:    .                 else if(*keyright && !*keyleft && !*keydown) {
 1009:    .                     me->ix += dx;
 1010:    .                     me->iy += dy;
 1011:    .                     if(direction != RIGHT) {
 1012:    .                         direction = RIGHT;
 1013:    .                         myobj->obj = occ;
 1014:                          }
 1015:                      }
 1016:    .                 else if(*keydown && !*keyleft && !*keyright) {
 1017:    .                     if(direction == LEFT) {
 1018:    .                         me->ix += dx;
 1019:    .                         me->iy += dy;
 1020:                          }
 1021:    .                     else if(direction == RIGHT) {
 1022:    .                         me->ix -= dx;
 1023:    .                         me->iy -= dy;
 1024:                          }
 1025:                      }
 1026:    .                 else {
 1027:    .                     dx *= 0.4;
 1028:    .                     dy *= 0.4;
 1029:    .                     if(me->ix > dx) {
 1030:    .                         me->ix -= dx;
 1031:    .                         if(me->iy > dy)
 1032:    .                             me->iy -= dy;
 1033:    .                         else if(me->iy < -dy)
 1034:    .                             me->iy += dy;
 1035:    .                         else
 1036:    .                             me->iy = 0;
 1037:                          }
 1038:    .                     else if(me->ix < -dx) {
 1039:    .                         me->ix += dx;
 1040:    .                         if(me->iy > dy)
 1041:    .                             me->iy -= dy;
 1042:    .                         else if(me->iy < -dy)
 1043:    .                             me->iy += dy;
 1044:    .                         else
 1045:    .                             me->iy = 0;
 1046:                          }
 1047:    .                     else {
 1048:    .                         me->ix = 0;
 1049:    .                         if(me->iy > dy)
 1050:    .                             me->iy -= dy;
 1051:    .                         else if(me->iy < -dy)
 1052:    .                             me->iy += dy;
 1053:    .                         else
 1054:    .                             me->iy = 0;
 1055:                          }
 1056:                      }
 1057:                  }
 1058:    .         }
 1059:          
 1060:              void update();
 1061:          };
 1062:          
 1063:    *     jeep jeeps[MAXJEEPS];
 1064:          int numjeeps;
 1065:          
 1066:          
 1067:          
 1068:    *     void addjeep(float nx, float ny) {
 1069:              jeep *j;
 1070:              rigidbody *r;
 1071:              int x, y;
 1072:          
 1073:    *         j = &(jeeps[0]);
 1074:    *         while(j->on) j++;
 1075:          
 1076:    *         settmplevels();
 1077:    *         tmplevels[1] = false;
 1078:    *         tmplevels[3] = false;
 1079:    *         tmplevels[4] = false;
 1080:    *         tmplevels[7] = false;
 1081:    *         tmplevels[11] = false;
 1082:    *         tmplevels[12] = false;
 1083:    *         j->on = true;
 1084:    *         r = addrigidobject("jeepu.pcx", nx, ny, false, tmplevels, 7, 0.025, 0.001, 70, 1);
 1085:    *         r->afric = 0.95;
 1086:    *         j->me = r;
 1087:    *         j->myobj = &(objects[numobjects - 1]);
 1088:    *         r->imult = 3;
 1089:    *         for(x = 0; x < 100; x++) {
 1090:    *             for(y = 0; y < 100; y++) {
 1091:    *                 if(structure[x][y] != NULL) {
 1092:    *                     structure[x][y]->damage = &(j->damage);
 1093:                      }
 1094:    *             }
 1095:    *         }
 1096:    *         j->init();
 1097:    *         if(j == &(jeeps[numjeeps]))
 1098:    *             numjeeps++;
 1099:    *     }
 1100:          
 1101:    *     void updatejeeps() {
 1102:              jeep *j;
 1103:              int i;
 1104:    *         j = &(jeeps[0]);
 1105:    *         for(i = 0; i < numjeeps; i++) {
 1106:    *             j->update();
 1107:    *             j++;
 1108:    *         }
 1109:    *     }
 1110:          
 1111:    *     jeep *byjeep(float x, float y) {
 1112:              jeep *j;
 1113:              int i;
 1114:          
 1115:    *         j = &(jeeps[0]);
 1116:    *         for(i = 0; i < numjeeps; i++) {
 1117:                  if( !j->destroyed && j->me != NULL && x < j->me->x + 8 && x > j->me->x - 8 &&
 1118:    *                 y < j->me->y + 15 && y >= j->me->y) {
 1119:    .                 return j;
 1120:                  }
 1121:    *             j++;
 1122:    *         }
 1123:    *         return NULL;
 1124:    *     }
 1125:          
 1126:          struct tank {
 1127:              rigidbody *me;
 1128:              bool occupied;
 1129:              float strength;
 1130:              object *myobj;
 1131:              BITMAP *base;
 1132:              BITMAP *barrel;
 1133:              /*
 1134:              BITMAP *base;
 1135:              BITMAP *basel;
 1136:              BITMAP *gunu;
 1137:              BITMAP *gunul;
 1138:              BITMAP *guno;
 1139:              BITMAP *gunol;
 1140:              BITMAP *exp;
 1141:              BITMAP *expl;
 1142:              BITMAP *barrel;
 1143:              BITMAP *barrell;
 1144:              */
 1145:              float damage;
 1146:              soldier *driver;
 1147:          
 1148:              volatile char *keyleft;
 1149:              volatile char *keyright;
 1150:              volatile char *keyup;
 1151:              volatile char *keydown;
 1152:              float tx, ty;
 1153:              bool *fire;
 1154:          
 1155:              //bool direction;
 1156:              //bool barreldirection;
 1157:              int engvoice;
 1158:              int engstartvoice;
 1159:              bool engstarted;
 1160:              bool destroyed;
 1161:              bool on;
 1162:          
 1163:              float speed;
 1164:              float barrelang;
 1165:              float goalang;
 1166:              //float cx, cy, 
 1167:              float x, y, ox, oy;
 1168:              float barrelspeed;
 1169:              float ca, sa, rca, rsa, oca, osa;
 1170:              float mk;               //just there for holdovers draw--dokeys
 1171:          
 1172:              int fired;
 1173:              int firing;
 1174:          
 1175:              float engramp;
 1176:              float engdir;
 1177:          
 1178:    *         tank() {
 1179:    *             reset();
 1180:    *         }
 1181:          
 1182:    *         void reset() {
 1183:    *             occupied = false;
 1184:                  //strength = 2.5;
 1185:    *             strength = 2.5;
 1186:    *             keyleft = &(key[KEY_A]);
 1187:    *             keyright = &(key[KEY_D]);
 1188:    *             keyup = &(key[KEY_W]);
 1189:    *             keydown = &(key[KEY_S]);
 1190:    *             destroyed = false;
 1191:    *             damage = 0;
 1192:    *             driver = NULL;
 1193:    *             on = false;
 1194:    *             speed = 0;
 1195:    *             barrelspeed = 1;
 1196:    *             fired = 0;
 1197:    *             barrel = tankbarrelanim[0];
 1198:    *             firing = 0;
 1199:    *             barrelang = 0;
 1200:    *             ca = 1;
 1201:    *             sa = 0;
 1202:    *             mk = 0;
 1203:    *             goalang = 0;
 1204:    *         }
 1205:          
 1206:    *         void init() {
 1207:    *             dovoices();
 1208:    *             barrel = tankbarrelanim[0];
 1209:    *         }
 1210:          
 1211:    *         void killvoices() {
 1212:    *             if(engvoice != NULL) deallocate_voice(engvoice);
 1213:    *             engvoice = NULL;
 1214:    *             if(engstartvoice != NULL) deallocate_voice(engstartvoice);
 1215:    *             engstartvoice = NULL;
 1216:    *         }
 1217:          
 1218:    *         void dovoices() {
 1219:    *             if(engvoice != NULL) deallocate_voice(engvoice);
 1220:    *             engvoice = allocate_voice(engine);
 1221:    *             voice_set_playmode(engvoice, PLAYMODE_LOOP);
 1222:    *             voice_start(engvoice);
 1223:    *             voice_set_volume(engvoice, 0);
 1224:    *             voice_set_priority(engvoice, 255);
 1225:    *             if(engstartvoice != NULL) deallocate_voice(engstartvoice);
 1226:    *             engstartvoice = allocate_voice(enginestart);
 1227:    *             voice_stop(engstartvoice);
 1228:    *         }
 1229:          
 1230:              void getin(soldier *);
 1231:          
 1232:              void draw();
 1233:          
 1234:    *         void erase() {
 1235:    *             if(destroyed) return;
 1236:                  //if(barreldirection == RIGHT) {
 1237:                      //blit(bg, buf, x - 35, y - 35, x - 35, y - 35, 70, 70);
 1238:                  //}
 1239:    *             blit(bg, buf, ox - 20, oy - 20, ox - 20, oy - 20, 40, 20);
 1240:                  //rectfill(buf, x - 15, y - 17, x + 15, y - 5, magenta);
 1241:    *         }
 1242:          
 1243:              void dokeys();
 1244:          
 1245:              void update();
 1246:          };
 1247:          
 1248:    *     tank tanks[MAXTANKS];
 1249:          int numtanks;
 1250:          
 1251:    *     tank *addtank(float nx, float ny, bool comp) {
 1252:              tank *j;
 1253:              rigidbody *r;
 1254:              int x, y;
 1255:          
 1256:    *         j = &(tanks[0]);
 1257:    *         while(j->on) j++;
 1258:          
 1259:    *         settmplevels();
 1260:    *         tmplevels[1] = false;
 1261:    *         tmplevels[3] = false;
 1262:    *         tmplevels[4] = false;
 1263:    *         tmplevels[5] = false;
 1264:    *         tmplevels[7] = false;
 1265:    *         tmplevels[9] = false;
 1266:    *         tmplevels[11] = false;
 1267:    *         tmplevels[12] = false;
 1268:    *         j->on = true;
 1269:              //r = addrigidobject("tanku.pcx", nx, ny, false, tmplevels, 7, 0.005, 0.0001, 100, 1);
 1270:              //r = addrigidobject("tanku.pcx", nx, ny, false, tmplevels, 7, 0.025, 0.001, 70, 1);
 1271:    *         if(!comp) r = addrigidobject("tanku.pcx", nx, ny, false, tmplevels, 7, 0.005, 0.0001, 600, 1);
 1272:    *         else r = addrigidobject("tankue.pcx", nx, ny, false, tmplevels, 7, 0.005, 0.0001, 600, 1);
 1273:    *         r->grmult = 10;
 1274:    *         r->grounddamagethreshold = 20;
 1275:          
 1276:              //r->afric = 0.95;
 1277:              //r->gfric = 0.007;
 1278:    *         r->imult = 1.5;
 1279:          
 1280:    *         j->me = r;
 1281:    *         j->myobj = &(objects[numobjects - 1]);
 1282:    *         for(x = 0; x < 100; x++) {
 1283:    *             for(y = 0; y < 100; y++) {
 1284:    *                 if(structure[x][y] != NULL) {
 1285:    *                     structure[x][y]->damage = &(j->damage);
 1286:                      }
 1287:    *             }
 1288:    *         }
 1289:    *         j->init();
 1290:    *         if(j == &(tanks[numtanks]))
 1291:    *             numtanks++;
 1292:    *         return j;
 1293:    *     }
 1294:          
 1295:    *     void updatetanks() {
 1296:              tank *j;
 1297:              int i;
 1298:    *         j = &(tanks[0]);
 1299:    *         for(i = 0; i < numtanks; i++) {
 1300:    *             j->update();
 1301:    *             j++;
 1302:    *         }
 1303:    *     }
 1304:          
 1305:    *     void drawtanks() {
 1306:              tank *j;
 1307:              int i;
 1308:    *         j = &(tanks[0]);
 1309:    *         for(i = 0; i < numtanks; i++) {
 1310:    *             j->draw();
 1311:    *             j++;
 1312:    *         }
 1313:    *     }
 1314:          
 1315:    *     void erasetanks() {
 1316:              tank *j;
 1317:              int i;
 1318:    *         j = &(tanks[0]);
 1319:    *         for(i = 0; i < numtanks; i++) {
 1320:    *             j->erase();
 1321:    *             j++;
 1322:    *         }
 1323:    *     }
 1324:          
 1325:    *     tank *bytank(float x, float y) {
 1326:              tank *j;
 1327:              int i;
 1328:          
 1329:    *         j = &(tanks[0]);
 1330:    *         for(i = 0; i < numtanks; i++) {
 1331:                  if( !j->destroyed && j->me != NULL && x < j->me->x + 8 && x > j->me->x - 8 &&
 1332:    *                 y < j->me->y + 15 && y >= j->me->y) {
 1333:    *                 return j;
 1334:                  }
 1335:    *             j++;
 1336:    *         }
 1337:    .         return NULL;
 1338:    *     }
 1339:          
 1340:    .     int calcdiff(float a, float b) {
 1341:    .         float d1 = abs(a - b);
 1342:    .         float d2 = 256 - d1;
 1343:    .         if(d1 < d2) {
 1344:    .             if(a > b) return -d1;
 1345:    .             else return d1;
 1346:              }
 1347:              else {
 1348:    .             if(a < b) return -d2;
 1349:    .             else return d2;
 1350:              }
 1351:    .     }
 1352:          
 1353:          struct plane {
 1354:              rigidbody *me;
 1355:              bool occupied;
 1356:              float strength;
 1357:              float force;
 1358:              object *myobj;
 1359:              BITMAP *unoc;
 1360:              BITMAP *occ;
 1361:              BITMAP *firing;
 1362:              BITMAP *exp;
 1363:              BITMAP *expl;
 1364:              BITMAP *damaged;
 1365:              BITMAP *damagedo;
 1366:              BITMAP *damagedf;
 1367:              float damage;
 1368:              soldier *driver;
 1369:          
 1370:              volatile char *keyleft;
 1371:              volatile char *keyright;
 1372:              volatile char *keyslow;
 1373:              volatile char *keyup;
 1374:              volatile char *keydown;
 1375:          
 1376:              bool direction;
 1377:              int engvoice;
 1378:              int engstartvoice;
 1379:              bool engstarted;
 1380:              bool destroyed;
 1381:              bool on;
 1382:              float speed;
 1383:              float engspeed;
 1384:              float proprot;
 1385:              float dx, dy, rx, ry;
 1386:              float goalspeed;
 1387:              int fired;
 1388:              int bfired;
 1389:              float sadd;
 1390:              float turning;
 1391:              float turnang;
 1392:              bool inturn;
 1393:              float tcos;
 1394:              bool noturn;
 1395:              bool isdamaged;
 1396:          
 1397:    *         plane() {
 1398:    *             reset();
 1399:    *         }
 1400:          
 1401:    *         void reset() {
 1402:    *             occupied = false;
 1403:    *             strength = 0.3;
 1404:    *             force = 40;
 1405:    *             keyleft = &(key[KEY_A]);
 1406:    *             keyright = &(key[KEY_D]);
 1407:    *             keyup = &(key[KEY_W]);
 1408:    *             keydown = &(key[KEY_S]);
 1409:    *             direction = RIGHT;
 1410:    *             destroyed = false;
 1411:    *             damage = 0;
 1412:    *             driver = NULL;
 1413:    *             on = false;
 1414:    *             engspeed = 0;
 1415:    *             proprot = pi / 2;
 1416:    *             goalspeed = 0;
 1417:    *             fired = 0;
 1418:    *             sadd = 0;
 1419:    *             turning = 0;
 1420:    *             direction = RIGHT;
 1421:    *             tcos = 1;
 1422:    *             noturn = false;
 1423:    *             turning = 0;
 1424:    *             turnang = 0;
 1425:    *             inturn = false;
 1426:    *             isdamaged = false;
 1427:    *         }
 1428:          
 1429:    .         void init() {
 1430:    .             myobj->obj = unoc;
 1431:    .             dovoices();
 1432:                  //addtrailanim(me->atomlist[1], smokeanim, 8, 3, rand()% 3, 100000, 0, 1, true, 3);
 1433:                  //addtrailanim(me->atomlist[1], smokeanim, 8, 10, rand()% 10, 100000, 0, 1, true, 10);
 1434:                  //addtrailanim(me->atomlist[1], smokeanim, 8, 10, rand()% 10, 100000, 0, 1, true, 10);
 1435:    .         }
 1436:          
 1437:    .         void killvoices() {
 1438:    .             if(engvoice != NULL) deallocate_voice(engvoice);
 1439:    .             engvoice = NULL;
 1440:    .             if(engstartvoice != NULL) deallocate_voice(engstartvoice);
 1441:    .             engstartvoice = NULL;
 1442:    .         }
 1443:          
 1444:    .         void dovoices() {
 1445:    .             if(engvoice != NULL) deallocate_voice(engvoice);
 1446:    .             engvoice = allocate_voice(prop);
 1447:    .             voice_set_playmode(engvoice, PLAYMODE_LOOP);
 1448:    .             voice_start(engvoice);
 1449:    .             voice_set_volume(engvoice, 0);
 1450:    .             voice_set_priority(engvoice, 255);
 1451:    .             if(engstartvoice != NULL) deallocate_voice(engstartvoice);
 1452:    .             engstartvoice = allocate_voice(propstart);
 1453:    .             voice_stop(engstartvoice);
 1454:    .         }
 1455:          
 1456:    .         void getin(soldier *newdriver) {
 1457:    .             noturn = true;
 1458:    .             driver = newdriver;
 1459:    .             if(destroyed) return;
 1460:    .             if(occupied == false) {
 1461:    .                 sadd = 20;
 1462:    .                 occupied = true;
 1463:    .                 if(voice_check(engstartvoice) != propstart) dovoices();
 1464:    .                 voice_start(engstartvoice);
 1465:    .                 dopanvol(me->x, 0.5);
 1466:    .                 voice_set_pan(engstartvoice, pan);
 1467:    .                 voice_set_volume(engstartvoice, vol);
 1468:    .                 release_voice(engstartvoice);
 1469:    .                 engstarted = false;
 1470:    .                 voice_set_position(engstartvoice, 0);
 1471:                      //voice_ramp_volume(engvoice, 100, 255);
 1472:    .                 if(!isdamaged) myobj->obj = occ;
 1473:    .                 else myobj->obj = damagedo;
 1474:                  }
 1475:    .             else {
 1476:    .                 me->ix *= 2;
 1477:    .                 me->iy *= 2;
 1478:    .                 engspeed += sadd;
 1479:    .                 sadd = 0;
 1480:    .                 voice_ramp_volume(engvoice, 100, 0);
 1481:    .                 occupied = false;
 1482:    .                 engstarted = false;
 1483:    .                 if(!isdamaged) myobj->obj = unoc;
 1484:    .                 else myobj->obj = damaged;
 1485:                  }
 1486:    .         }
 1487:          
 1488:    .         void draw() {
 1489:    .             if(me == NULL) return;
 1490:                  float cx, cy, ox, oy, o;
 1491:                  int points[14];
 1492:    .             cx = me->polylistx[16] + dx*2*tcos + rx*2;
 1493:    .             cy = me->polylisty[16] + dy*2*tcos + ry*2;
 1494:    .             o = sin(proprot);
 1495:    .             ox = o * rx;
 1496:    .             oy = o * ry;
 1497:          
 1498:                  
 1499:                  //if(frame % 5 == 0) {
 1500:                      //fprintf(debug, "c");
 1501:                      //fprintf(debug, "\n%i, %i, %i, %i\n", me, anim, animframes, randoff);
 1502:                  //addanimation(smokeanim, 8, me->atomlist[1]->x - 15, me->atomlist[1]->y - 15, true, 0, 1);
 1503:                      //fprintf(debug, "d");
 1504:                  //}
 1505:          
 1506:    .             points[0] = (int)(cx);
 1507:    .             points[1] = (int)(cy);
 1508:    .             points[2] = (int)(cx - 7*ox - .5*dx);
 1509:    .             points[3] = (int)(cy - 7*oy - .5*dy);
 1510:    .             points[4] = (int)(cx - 7*ox + .5*dx);
 1511:    .             points[5] = (int)(cy - 7*oy + .5*dy);
 1512:    .             points[6] = (int)(cx);
 1513:    .             points[7] = (int)(cy);
 1514:    .             points[8] = (int)(cx + 7*ox - .5*dx);
 1515:    .             points[9] = (int)(cy + 7*oy - .5*dy);
 1516:    .             points[10] = (int)(cx + 7*ox + .5*dx);
 1517:    .             points[11] = (int)(cy + 7*oy + .5*dy);
 1518:    .             points[12] = (int)(cx);
 1519:    .             points[13] = (int)(cy);
 1520:          
 1521:                  /*
 1522:                  points[0] = (int)(cx + 0.5*dx);
 1523:                  points[1] = (int)(cy + 0.5*dy);
 1524:                  points[2] = (int)(cx - 7*ox);
 1525:                  points[3] = (int)(cy - 7*oy);
 1526:                  points[4] = (int)(cx - 7*ox + 1*dx);
 1527:                  points[5] = (int)(cy - 7*oy + 1*dy);
 1528:                  points[6] = (int)(cx + 0.5*dx);
 1529:                  points[7] = (int)(cy + 0.5*dy);
 1530:                  points[8] = (int)(cx + 7*ox);
 1531:                  points[9] = (int)(cy + 7*oy);
 1532:                  points[10] = (int)(cx + 7*ox + 1*dx);
 1533:                  points[11] = (int)(cy + 7*oy + 1*dy);
 1534:                  points[12] = (int)(cx + 0.5*dx);
 1535:                  points[13] = (int)(cy + 0.5*dy);
 1536:                  */
 1537:    .             polygon(buf, 7, points, black);
 1538:          
 1539:                  //lx = cx;
 1540:                  //ly = cy;
 1541:    .             if(engstarted || !occupied)
 1542:    .                 proprot += 0.02 * (0.5 * engspeed + sadd);
 1543:          
 1544:                  //line(buf, lx, ly, ux, uy, gray);
 1545:          
 1546:    .         }
 1547:          
 1548:    .         void erase() {
 1549:    .             if(me == NULL) return;
 1550:                  float ox, oy;
 1551:    .             ox = me->atomlist[16]->x - me->x;
 1552:    .             oy = me->atomlist[16]->y - me->y;
 1553:    .             ox *= tcos;
 1554:    .             oy *= tcos;     
 1555:                  //blit(bg, buf, me->atomlist[16]->x - 10, me->atomlist[16]->y - 10, me->atomlist[16]->x - 10, me->atomlist[16]->y - 10, 20, 20);
 1556:    .             blit(bg, buf, me->x + ox - 10, me->y + oy - 10, me->x + ox - 10, me->y + oy - 10, 20, 20);
 1557:    .         }
 1558:          
 1559:              void dokeys();
 1560:          
 1561:              void update();
 1562:          };
 1563:          
 1564:    *     plane planes[MAXPLANES];
 1565:          int numplanes;
 1566:          
 1567:    *     aagun *byaagun(float x, float y) {
 1568:              aagun *j;
 1569:              int i;
 1570:          
 1571:    *         j = &(aaguns[0]);
 1572:    *         for(i = 0; i < numaaguns; i++) {
 1573:    .             putpixel(bg, j->x, j->y, green);
 1574:    .             putpixel(buf, j->x, j->y, green);
 1575:                  if( !j->destroyed && x < j->x + 39 && x > j->x + 19 &&
 1576:    .                 y < j->y + 46 && y >= j->y + 31) {
 1577:    .                 return j;
 1578:                  }
 1579:    .             j++;
 1580:    .         }
 1581:    *         return NULL;
 1582:    *     }
 1583:          
 1584:    .     void addplane(float nx, float ny) {
 1585:              plane *j;
 1586:              rigidbody *r;
 1587:              int x, y;
 1588:          
 1589:    .         j = &(planes[0]);
 1590:    .         while(j->on) j++;
 1591:          
 1592:    .         ny -= 100;
 1593:    .         settmplevels();
 1594:    .         tmplevels[1] = false;
 1595:    .         tmplevels[3] = false;
 1596:    .         tmplevels[4] = false;
 1597:    .         tmplevels[9] = false;
 1598:    .         j->on = true;
 1599:              //r = addrigidobject("planeu.pcx", nx, ny, false, tmplevels, 7, 0.025, 0.001, 0, 1.1);
 1600:    .         r = addrigidobject("planed.pcx", nx, ny, false, tmplevels, 7, 0.025, 0.001, 0, 1.1);
 1601:              //r = addrigidobject("heli.pcx", nx, ny, false, tmplevels, 7, 0.025, 0.001, 0, 1.1);
 1602:    .         r->afric = FLUIDFRICTION;
 1603:    .         j->me = r;
 1604:    .         j->myobj = &(objects[numobjects - 1]);
 1605:    .         for(x = 0; x < 100; x++) {
 1606:    .             for(y = 0; y < 100; y++) {
 1607:    .                 if(structure[x][y] != NULL) {
 1608:    .                     structure[x][y]->damage = &(j->damage);
 1609:                      }
 1610:    .             }
 1611:    .         }
 1612:    .         j->init();
 1613:    .         if(j == &(planes[numplanes]))
 1614:    .             numplanes++;
 1615:    .     }
 1616:          
 1617:    *     void updateplanes() {
 1618:              plane *j;
 1619:              int i;
 1620:    *         j = &(planes[0]);
 1621:    *         for(i = 0; i < numplanes; i++) {
 1622:    .             j->update();
 1623:    .             j++;
 1624:    .         }
 1625:    *     }
 1626:          
 1627:    *     void drawplanes() {
 1628:              plane *j;
 1629:              int i;
 1630:    *         j = &(planes[0]);
 1631:    *         for(i = 0; i < numplanes; i++) {
 1632:    .             j->draw();
 1633:    .             j++;
 1634:    .         }
 1635:    *     }
 1636:          
 1637:    *     void eraseplanes() {
 1638:              plane *j;
 1639:              int i;
 1640:    *         j = &(planes[0]);
 1641:    *         for(i = 0; i < numplanes; i++) {
 1642:    .             j->erase();
 1643:    .             j++;
 1644:    .         }
 1645:    *     }
 1646:          
 1647:    *     plane *byplane(float x, float y) {
 1648:              plane *j;
 1649:              int i;
 1650:          
 1651:    *         j = &(planes[0]);
 1652:    *         for(i = 0; i < numplanes; i++) {
 1653:                  if( !j->destroyed && j->me != NULL && x < j->me->x + 8 && x > j->me->x - 8 &&
 1654:    .                 y < j->me->y + 15 && y >= j->me->y) {
 1655:    .                 return j;
 1656:                  }
 1657:    .             j++;
 1658:    .         }
 1659:    *         return NULL;
 1660:    *     }
 1661:          
 1662:          struct soldier {
 1663:              atom *me;
 1664:              atom *abody;
 1665:              BITMAP *bodyl;
 1666:              BITMAP *bodyr;
 1667:              BITMAP *body;
 1668:              BITMAP *arm;
 1669:              BITMAP *armbuf;
 1670:              BITMAP *head;
 1671:              BITMAP *headbuf;
 1672:              BITMAP *transbuf;
 1673:          
 1674:              volatile char *keyleft;
 1675:              volatile char *keyright;
 1676:              volatile char *keyup;
 1677:              volatile char *keydown;
 1678:              volatile char *keygetin;
 1679:          
 1680:              float force;
 1681:              float strength;
 1682:              float jumpstrength;
 1683:              float bulletforce;
 1684:              int firedelay;
 1685:          
 1686:              float angle, fangle;
 1687:              float tmp1, tmp2;
 1688:              int offx, offy, bodyw, bodyh;
 1689:              bool direction;
 1690:              bool tmp;
 1691:              bool invehicle;
 1692:              bool gotin;
 1693:              bool *fire;
 1694:              int fired;
 1695:              float tx, ty;
 1696:              bool comp;
 1697:              bool drew;
 1698:              float damage;
 1699:              float health;
 1700:              bool dead;
 1701:              int gunvoice;
 1702:              jeep *injeep;
 1703:              tank *intank;
 1704:              plane *inplane;
 1705:              aagun *inaagun;
 1706:              int walkframe;
 1707:              
 1708:              float gunramp;
 1709:              float gunrampdir;
 1710:          
 1711:              bool firing;
 1712:          
 1713:    *         soldier() {
 1714:    *             reset();
 1715:    *         }
 1716:          
 1717:    *         void reset() {
 1718:    *             keyleft = &(key[KEY_A]);
 1719:    *             keyright = &(key[KEY_D]);
 1720:    *             keyup = &(key[KEY_W]);
 1721:    *             keydown = &(key[KEY_S]);
 1722:    *             keygetin = &(key[KEY_SPACE]);
 1723:          
 1724:    *             gunramp = 0;
 1725:    *             gunrampdir = 0;
 1726:          
 1727:    *             force = 1.7;
 1728:    *             strength = .015;
 1729:    *             jumpstrength = 0.5;
 1730:    *             bulletforce = 3;
 1731:    *             me = NULL;
 1732:    *             firing = false;
 1733:          
 1734:    *             offx = offy = 0;
 1735:    *             direction = RIGHT;
 1736:    *             angle = 0;
 1737:    *             firedelay = 30;
 1738:    *             fired = 0;
 1739:    *             invehicle = false;
 1740:    *             gotin = false;
 1741:    *             comp = false;
 1742:    *             fire = false;
 1743:    *             dead = false;
 1744:          
 1745:    *             tx = ty = 0;
 1746:    *             health = 100;
 1747:    *             gunvoice = -1;
 1748:    *             damage = 0;
 1749:    *             drew = false;
 1750:    *             injeep = NULL;
 1751:    *             intank = NULL;
 1752:    *             inplane = NULL;
 1753:    *             inaagun = NULL;
 1754:    *             walkframe = 0;
 1755:    *         }
 1756:          
 1757:    *         void killvoices() {
 1758:    *             if(gunvoice != NULL) deallocate_voice(gunvoice);
 1759:    *             gunvoice = NULL;
 1760:    *         }
 1761:          
 1762:    *         void dovoices() {
 1763:    *             if(gunvoice != NULL) deallocate_voice(gunvoice);
 1764:    *             gunvoice = allocate_voice(mgun);
 1765:    *             voice_set_playmode(gunvoice, PLAYMODE_LOOP);
 1766:    *             voice_set_volume(gunvoice, 255);
 1767:                  //play_sample(mgun, 255, 122, 1000, 0);
 1768:                  //voice_set_frequency(gunvoice, 8000);
 1769:    *             voice_stop(gunvoice);
 1770:    *         }
 1771:          
 1772:    *         void init(atom *newme) {
 1773:    *             me = newme;
 1774:    *             me->draw = false;
 1775:    *             me->damage = &damage;
 1776:                  
 1777:    *             if(!comp) {
 1778:    *                 head = load_bitmap("soldierhead.pcx", NULL);
 1779:    *                 arm = load_bitmap("soldierarm.pcx", NULL);
 1780:    *                 bodyr = load_bitmap("soldierbody.pcx", NULL);
 1781:                  }
 1782:    *             else {
 1783:    *                 head = load_bitmap("soldierheade.pcx", NULL);
 1784:    *                 arm = load_bitmap("soldierarme.pcx", NULL);
 1785:    *                 bodyr = load_bitmap("soldierbodye.pcx", NULL);
 1786:                  }
 1787:    *             bodyl = create_bitmap(bodyr->w, bodyr->h);
 1788:    *             clear_to_color(bodyl, magenta);
 1789:    *             draw_sprite_h_flip(bodyl, bodyr, 0, 0);
 1790:          
 1791:    *             bodyw = 28;
 1792:    *             bodyh = 28;
 1793:    *             offx = -bodyw / 2;
 1794:    *             offy = -bodyh + 8;
 1795:    *             body = bodyr;
 1796:          
 1797:    *             transbuf = create_bitmap(bodyh, bodyh);
 1798:    *             clear_to_color(transbuf, magenta);
 1799:    *             armbuf = create_bitmap(26, 26);
 1800:    *             clear_to_color(armbuf, magenta);
 1801:    *             headbuf = create_bitmap(head->h + 8, head->h + 10);
 1802:    *             clear_to_color(transbuf, magenta);
 1803:          
 1804:    *             abody = addatom(me->x, me->y - 12, me->levels, me->level);
 1805:    *             abody->draw = false;
 1806:    *             abody->levels[2] = false;
 1807:    *             abody->damage = &damage;
 1808:    *             dovoices();
 1809:    *         }
 1810:          
 1811:    *         void draw() {
 1812:                  //if(dead) return;
 1813:                  //textprintf(buf, font, me->x - 200, 70, white, "Level: %i, levels[14]: %i", me->level, me->levels[14]);
 1814:    *             if(invehicle || dead) return;
 1815:    *             if(me->x + 5 > lx && me->x - 5 < rx) {
 1816:    *                 clear_to_color(transbuf, magenta);
 1817:    *                 clear_to_color(headbuf, magenta);
 1818:    *                 clear_to_color(armbuf, magenta);
 1819:          
 1820:    *                 if(!comp) {
 1821:    *                     angle = atan2(my - me->y + 8, mx - me->x);
 1822:                      }
 1823:    *                 else {
 1824:    *                     angle = atan2(ty - me->y + 8, tx - me->x);
 1825:                      }
 1826:          
 1827:    *                 fangle = angle * convk;
 1828:                      
 1829:    *                 if(fangle < -64 || fangle > 64) {
 1830:    *                     direction = LEFT;
 1831:    *                     fangle = 128 - fangle;
 1832:    *                     if(fangle > 128) fangle -= 256;
 1833:                      }
 1834:    *                 else {
 1835:    *                     direction = RIGHT;
 1836:                      }
 1837:          
 1838:                      //if(angle < 128 && angle > 64) angle = 64;
 1839:                      //else if(angle < 200) angle = 200;
 1840:    *                 if(fangle > 50) fangle = 50;
 1841:    *                 if(fangle < -64) fangle = -64;
 1842:          
 1843:                      //draw_sprite(transbuf, body, 10, 9);
 1844:    *                 blit(body, transbuf, walkframe * 19, 0, 5, 9, 19, 19);
 1845:    *                 pivot_sprite(armbuf, arm, 15, 13, 3, 2, itofix((int)fangle));
 1846:    *                 pivot_sprite(headbuf, head, 9, 9, 4, 7, itofix((int)fangle));
 1847:    *                 draw_sprite(transbuf, armbuf, 0, 0);
 1848:    *                 draw_sprite(transbuf, headbuf, 5, 0);
 1849:    *                 if(direction == RIGHT)
 1850:    *                     draw_sprite(buf, transbuf, me->x + offx, me->y + offy);
 1851:    *                 else
 1852:    *                     draw_sprite_h_flip(buf, transbuf, me->x + offx, me->y + offy);
 1853:    *                 drew = true;
 1854:                  }
 1855:    *         }
 1856:          
 1857:    *         void erase() {
 1858:    *             if(!drew) return;
 1859:    *             if(invehicle || dead) return;
 1860:    *             blit(bg, buf, me->x + offx, me->y + offy, me->x + offx, me->y + offy, bodyw, bodyh);
 1861:    *             drew = false;
 1862:    *         }
 1863:          
 1864:    *         void dokeys() {
 1865:    *             if(dead) return;
 1866:          
 1867:                  float appstrength;
 1868:                  float cx, cy, cd;
 1869:          
 1870:    *             cx = me->ix - me->oix;
 1871:    *             cy = me->iy - me->oiy;
 1872:          
 1873:    *             cy -= GRAVITY;
 1874:    *             cd = sqrt(cx * cx + cy * cy);
 1875:    *             cd = fabs(cd);
 1876:                  //if(cd > 1) {
 1877:                      //health -= (cd - 1);
 1878:                  //}
 1879:                  
 1880:    *             if(comp)
 1881:    *                 health -= 20 * damage;
 1882:    *             else
 1883:    *                 health -= 5 * damage;
 1884:    *             damage = 0;
 1885:          
 1886:    *             if(health <= 0 || me->y > waterlevel) {
 1887:    *                 health = 0;
 1888:    *                 dead = true;
 1889:    *                 dopanvol(me->x, 0.2);
 1890:    *                 play_sample(death1, vol, pan, 1000, 0);
 1891:    *                 deallocate_voice(gunvoice);
 1892:    *                 voice_ramp_volume(gunvoice, 50, 0);
 1893:    *                 gunramp = 0;
 1894:    *                 gunrampdir = -0.1;
 1895:    *                 gunvoice = NULL;
 1896:    *                 if(invehicle) {
 1897:    .                     if(injeep != NULL) injeep->getin(this);
 1898:    .                     if(intank != NULL) intank->getin(this);
 1899:    .                     if(inplane != NULL) inplane->getin(this);
 1900:    .                     if(inaagun != NULL) inaagun->getin(this);
 1901:                      }
 1902:    *                 cleartmplevels();
 1903:                      //tmplevels[8] = true;
 1904:    *                 if(comp) {
 1905:    *                     if(direction == RIGHT)
 1906:    .                         addobject("soldierder.pcx", NULL, me->x - 20, me->y - 27, 0, tmplevels, 8, 1000);
 1907:    .                     else
 1908:    *                         addobject("soldierdel.pcx", NULL, me->x - 20, me->y - 27, 0, tmplevels, 8, 1000);
 1909:                      }
 1910:    *                 else {
 1911:    *                     if(direction == RIGHT)
 1912:    *                         addobject("soldierdr.pcx", NULL, me->x - 20, me->y - 27, 0, tmplevels, 8, 1000);
 1913:    *                     else
 1914:    .                         addobject("soldierdl.pcx", NULL, me->x - 20, me->y - 27, 0, tmplevels, 8, 1000);
 1915:                      }
 1916:    *                 structure[1][0]->ix = me->ix * 0.4;
 1917:    *                 structure[2][0]->ix = me->ix * 0.4;
 1918:    *                 structure[1][1]->ix = me->ix * 0.2;
 1919:    *                 structure[2][1]->ix = me->ix * 0.2;
 1920:    *                 if(me->y < waterlevel) {
 1921:    *                     structure[1][0]->iy = me->ix * 0.2 - 1;
 1922:    *                     structure[2][0]->iy = me->ix * 0.2 - 1;
 1923:    *                     structure[1][1]->iy = me->ix * 0.1 - 1;
 1924:    *                     structure[2][1]->iy = me->ix * 0.1 - 1;
 1925:                      }
 1926:    *                 else {
 1927:    .                     structure[1][0]->iy = me->iy * 0.2;
 1928:    .                     structure[2][0]->iy = me->iy * 0.2;
 1929:    .                     structure[1][1]->iy = me->iy * 0.1;
 1930:    .                     structure[2][1]->iy = me->iy * 0.1;
 1931:                      }
 1932:    *                 if((structure[1][0]->ix > -0.2 && structure[1][0]->ix < 0.2)) {// || (structure[1][0]->ix < -1 || structure[1][0]->ix > 1)) {
 1933:    .                     if(direction == RIGHT) {
 1934:    .                         structure[1][0]->ix = -.4;
 1935:    .                         structure[2][0]->ix = -.4;
 1936:    .                         structure[1][1]->ix = -.2;
 1937:    .                         structure[2][1]->ix = -.2;
 1938:                          }
 1939:    .                     else {
 1940:    .                         structure[1][0]->ix = .4;
 1941:    .                         structure[2][0]->ix = .4;
 1942:    .                         structure[1][1]->ix = .2;
 1943:    .                         structure[2][1]->ix = .2;
 1944:                          }
 1945:                      }
 1946:    *                 erase();
 1947:    *                 if(me != center)
 1948:    *                     destroyatom(me);
 1949:    *                 else {
 1950:    *                     center->rmdt = 0.00001;
 1951:    *                     center->fixed = true;
 1952:                      }
 1953:    *                 destroyatom(abody);
 1954:    *                 me = NULL;
 1955:    *                 abody = NULL;
 1956:    *                 return;
 1957:                  }
 1958:          
 1959:    *             appstrength = strength * COMPFRAMES;
 1960:          
 1961:          
 1962:    *             if(!gotin && injeep == NULL && inplane == NULL && intank == NULL && inaagun == NULL && *keygetin) {//!jeep1.destroyed 
 1963:    *                 injeep = byjeep(me->x, me->y);
 1964:    *                 if(injeep != NULL) {
 1965:    .                     invehicle = true;
 1966:    .                     injeep->getin(this);
 1967:    .                     gotin = true;
 1968:                      }
 1969:    .                 else {              
 1970:    *                     inaagun = byaagun(me->x, me->y);
 1971:    *                     if(inaagun != NULL) {
 1972:    .                         invehicle = true;
 1973:    .                         inaagun->getin(this);
 1974:    .                         gotin = true;
 1975:                          }
 1976:    .                     else {
 1977:    *                         inplane = byplane(me->x, me->y);
 1978:    *                         if(inplane != NULL) {
 1979:    .                             invehicle = true;
 1980:    .                             inplane->getin(this);
 1981:    .                             gotin = true;
 1982:                              }
 1983:    .                         else {
 1984:    *                             intank = bytank(me->x, me->y);
 1985:    *                             if(intank != NULL) {
 1986:    *                                 invehicle = true;
 1987:    *                                 intank->getin(this);
 1988:    *                                 gotin = true;
 1989:                                  }
 1990:                              }
 1991:                          }
 1992:                      }
 1993:                      
 1994:                      /*&& *keygetin && 
 1995:                      me->x < jeep1.me->x + 8 && me->x > jeep1.me->x - 8 &&
 1996:          
 1997:                      me->y < jeep1.me->y + 15 && me->y >= jeep1.me->y            
 1998:                      ) {
 1999:                      invehicle = !invehicle;
 2000:                      jeep1.getin(this);
 2001:                      gotin = true;
 2002:                      */
 2003:                  }
 2004:    *             else if(!gotin && injeep != NULL && *keygetin) {
 2005:    .                 injeep->getin(this);
 2006:    .                 invehicle = false;
 2007:    .                 gotin = true;
 2008:    .                 injeep = NULL;
 2009:                  }
 2010:    .             else if(!gotin && inplane != NULL && *keygetin) {
 2011:    .                 inplane->getin(this);
 2012:    .                 invehicle = false;
 2013:    .                 gotin = true;
 2014:    .                 inplane = NULL;
 2015:                  }
 2016:    .             else if(!gotin && inaagun != NULL && *keygetin) {
 2017:    .                 inaagun->getin(this);
 2018:    .                 invehicle = false;
 2019:    .                 gotin = true;
 2020:    .                 inaagun = NULL;
 2021:                  }
 2022:    .             else if(!gotin && intank != NULL && *keygetin) {
 2023:    .                 intank->getin(this);
 2024:    .                 invehicle = false;
 2025:    .                 gotin = true;
 2026:    .                 intank = NULL;
 2027:                  }
 2028:    .             else if(!*keygetin) {
 2029:    *                 gotin = false;
 2030:                  }
 2031:          
 2032:    *             if(invehicle) return;
 2033:          
 2034:    *             if(me->y > path[(int)(me->x)] - 6) {
 2035:    *                 if(*keyleft && !*keyright) {
 2036:                          //body = bodyl;
 2037:    *                     if(me->ix > -force + appstrength) {
 2038:    *                         me->ix -= appstrength;
 2039:                          }
 2040:    *                     else if(me->ix > -force) {
 2041:    *                         me->ix = -force;
 2042:                          }
 2043:    *                     if(dispframe) walkframe++;
 2044:                      }
 2045:    *                 else if(*keyright && !*keyleft) {
 2046:                          // body = bodyr;
 2047:    *                     if(me->ix < force - appstrength) {
 2048:    *                         me->ix += appstrength;
 2049:                          }
 2050:    *                     else if(me->ix < force) {
 2051:    *                         me->ix = force;
 2052:                          }
 2053:    *                     if(dispframe) walkframe++;
 2054:                      }
 2055:    *                 else {
 2056:    *                     if(me->ix < -appstrength) {
 2057:    *                         me->ix += appstrength;
 2058:                          }
 2059:    *                     else if(me->ix > appstrength) {
 2060:    *                         me->ix -= appstrength;
 2061:                          }
 2062:    *                     else {
 2063:    *                         me->ix = 0;
 2064:                          }
 2065:    *                     walkframe = 0;
 2066:                      }
 2067:    *                 if(walkframe >= 8) walkframe = 0;
 2068:          
 2069:    *                 if(*keyup) {
 2070:    .                     me->iy -= jumpstrength * COMPFRAMES;
 2071:    .                     if(cy < 0) {
 2072:    .                         if(*keyleft && !*keyright) {
 2073:    .                             me->ix -= appstrength;
 2074:                              }
 2075:    .                         else if(*keyright && !*keyleft) {
 2076:    .                             me->ix += appstrength;
 2077:                              }
 2078:                          }
 2079:    .                     else {
 2080:    .                         if(*keyleft && !*keyright) {
 2081:    .                             me->ix -= 2*appstrength;
 2082:                              }
 2083:    .                         else if(*keyright && !*keyleft) {
 2084:    .                             me->ix += 2*appstrength;
 2085:                              }
 2086:                          }
 2087:                      }
 2088:                  }
 2089:          
 2090:    *             if(((!comp && mouse_b & 1) || (comp && *fire)) && fired <= 0) {
 2091:    *                 if(voice_check(gunvoice) != mgun) dovoices();
 2092:    *                 gunrampdir = 0.1;
 2093:    *                 voice_set_playmode(gunvoice, PLAYMODE_LOOP);
 2094:    *                 firing = true;
 2095:    *                 tmp1 = cos(angle);
 2096:    *                 tmp2 = sin(angle);
 2097:    *                 addbullet(me->x + 13 * tmp1, me->y - 8 + 13 * tmp2, bulletforce * tmp1, bulletforce * tmp2, comp, 100, 1, 1, gray, false);
 2098:    *                 fired = firedelay;
 2099:    *                 voice_start(gunvoice);
 2100:                  }
 2101:    *             if(fired > -10) fired--;
 2102:    *             if(fired < -5) {
 2103:    *                 voice_ramp_volume(gunvoice, 50, 0);
 2104:    *                 firing = false;
 2105:                      //voice_set_playmode(gunvoice, 0);//, PLAYMODE_BACKWARD);
 2106:                      //if(voice_get_position(gunvoice) <= 10) voice_stop(gunvoice);
 2107:                      //voice_set_position(gunvoice, 0);
 2108:                  }
 2109:    *         }
 2110:          
 2111:    *         void update() {
 2112:    *             if(dead) return;
 2113:          
 2114:    *             if(gunrampdir > 0) {
 2115:    *                 gunramp += gunrampdir;
 2116:    *                 if(gunramp >= 1) {
 2117:    *                     gunrampdir = 0;
 2118:    *                     gunramp = 1;
 2119:                      }
 2120:                  }
 2121:    *             else if(gunrampdir < 0) {
 2122:    .                 gunramp += gunrampdir;
 2123:    .                 if(gunramp <= 0) {
 2124:    .                     gunrampdir = 0;
 2125:    .                     gunramp = 0;
 2126:                      }
 2127:                  }
 2128:          
 2129:    *             if(firing) {
 2130:    *                 dopanvol(me->x, 0.3);
 2131:    *                 voice_set_pan(gunvoice, pan);
 2132:    *                 voice_set_volume(gunvoice, vol * gunramp);
 2133:                  }
 2134:          
 2135:    *             if(invehicle) {
 2136:    *                 if(injeep != NULL) {
 2137:    .                     me->x = injeep->me->x;
 2138:    .                     me->y = injeep->me->y;
 2139:    .                     me->ix = injeep->me->ix * 0.1;
 2140:    .                     me->iy = injeep->me->iy * 0.1;
 2141:                      }
 2142:    .                 else if(intank != NULL) {
 2143:    *                     me->x = intank->me->x;
 2144:    *                     me->y = intank->me->y;
 2145:    *                     me->ix = intank->me->ix * 0.0;
 2146:    *                     me->iy = intank->me->iy * 0.0;
 2147:                      }
 2148:    *                 else if(inplane != NULL) {
 2149:    .                     me->x = inplane->me->x;
 2150:    .                     me->y = inplane->me->y;
 2151:    .                     me->ix = inplane->me->ix * 0.1;
 2152:    .                     me->iy = inplane->me->iy * 0.1;
 2153:                      }
 2154:    .                 else if(inaagun != NULL) {
 2155:    .                     me->x = inaagun->x + 29;
 2156:    .                     me->y = inaagun->y + 36;
 2157:    .                     me->ix = 0;
 2158:    .                     me->iy = 0;
 2159:                      }
 2160:    *                 abody->x = me->x;
 2161:    *                 abody->y = me->y - 12;
 2162:    *                 abody->ix = 0;
 2163:    *                 abody->iy = 0;
 2164:                  }
 2165:    *             else {
 2166:    *                 me->ix += abody->ix;
 2167:    *                 abody->ix = 0;
 2168:    *                 abody->iy = 0;
 2169:    *                 abody->x = me->x;
 2170:    *                 abody->y = me->y - 12;
 2171:                  }
 2172:    *             dokeys();
 2173:    *         }
 2174:          };
 2175:          
 2176:    *     soldier soldiers[MAXSOLDIERS];
 2177:          int numsoldiers;
 2178:          soldier *human;
 2179:          
 2180:    .     void aagun::update() {
 2181:              float dx, dy;
 2182:              int tmpv;
 2183:              bullet *b;
 2184:          
 2185:    .         if(occupied) {
 2186:                  float goalangle;
 2187:                  
 2188:    .             if(!driver->comp) {
 2189:    .                 if(direction == RIGHT) {
 2190:    .                     goalangle = atan2(my + 3 - (y + 30), mx - (x + 30));
 2191:                      }
 2192:    .                 else {
 2193:    .                     goalangle = atan2(my + 3 - (y + 30), mx - (x + 36));
 2194:                      }
 2195:                  }
 2196:    .             else {
 2197:    .                 if(direction == RIGHT) {
 2198:    .                     goalangle = atan2(ty + 3 - (y + 30), tx - (x + 30));
 2199:                      }
 2200:    .                 else {
 2201:    .                     goalangle = atan2(ty + 3 - (y + 30), tx - (x + 36));
 2202:                      }
 2203:                  }
 2204:    .             fangle = goalangle * convk;
 2205:          
 2206:    .             if(direction == RIGHT && angle <= 128) {//(angle < -64 || angle > 64)) {            
 2207:    .                 direction = LEFT;
 2208:                  }
 2209:    .             else if(direction == LEFT && angle > 128) {//(angle < -64 || angle > 64)) {         
 2210:    .                 direction = RIGHT;
 2211:                  }
 2212:          
 2213:    .             fangle += 192;
 2214:    .             if(fangle > 256) fangle -= 256;
 2215:          
 2216:    .             if(fangle < 45) fangle = 45;
 2217:    .             if(fangle > 211) fangle = 211;
 2218:          
 2219:    .             if(angle - speed < fangle) {
 2220:    .                 angle += speed;
 2221:                  }
 2222:    .             else if(angle + speed > fangle) {
 2223:    .                 angle -= speed;
 2224:                  }
 2225:          
 2226:    .             dangle = angle - 192;
 2227:    .             if(direction == LEFT) dangle = 128 - dangle;
 2228:    .             if(dangle < 0) dangle += 256;
 2229:              }
 2230:    .         if(occupied || (!occupied && numfired > 0)) {
 2231:    .             if(fired <= 0 && (numfired > 0 || (occupied && driver->comp && *fire) || (occupied && !driver->comp && mouse_b & 1))) {
 2232:    .                 dx = cos((angle + 64) * convk2);
 2233:    .                 dy = sin((angle + 64) * convk2);
 2234:                      //if(voice_check(driver->gunvoice) != mgun) driver->dovoices();
 2235:                      //voice_ramp_volume(driver->gunvoice, 50, 255);
 2236:                      //voice_set_playmode(driver->gunvoice, PLAYMODE_LOOP);
 2237:    .                 if(direction == RIGHT)
 2238:    .                     b = addbullet(x + 29 + 36 * dx, y + 28 + 36 * dy, bulletforce * dx, bulletforce * dy, (occupied && driver->comp), 400, 1, 3, yellow, false);
 2239:    .                 else
 2240:    .                     b = addbullet(x + 35 + 36 * dx, y + 28 + 36 * dy, bulletforce * dx, bulletforce * dy, (occupied && driver->comp), 400, 1, 3, yellow, false);
 2241:    .                 if(b != NULL) {
 2242:    .                     b->me->rmdt = 0.1;
 2243:    .                     b->me->dmult = 100;
 2244:                      }
 2245:                      //myobj->obj = firing;
 2246:                      //voice_start(driver->gunvoice);
 2247:    .                 if(numfired == 0) {
 2248:    .                     tmpv = allocate_voice(aagunfire);
 2249:    .                     voice_set_priority(tmpv, 255);
 2250:    .                     voice_start(tmpv);
 2251:    .                     release_voice(tmpv);
 2252:                      }
 2253:    .                 numfired++;
 2254:    .                 if(numfired == 6) {
 2255:    .                     fired = 200;
 2256:    .                     numfired = 0;
 2257:                      }
 2258:    .                 else {
 2259:    .                     fired = 35;
 2260:                      }
 2261:                  }
 2262:    .             if(fired > -10) fired--;
 2263:                  /*
 2264:                  if(fired <= 5 && myobj->obj == firing) {
 2265:                      if(occupied) myobj->obj = occ;
 2266:                      else myobj->obj = unoc;
 2267:                  }
 2268:                  if(fired < -5) {
 2269:                      voice_ramp_volume(driver->gunvoice, 50, 0);
 2270:                  }
 2271:                  */
 2272:              }
 2273:    .     }
 2274:              
 2275:    .     void aagun::draw() {
 2276:    .         if(x + w > lx && x < rx) {
 2277:    .             clear_to_color(hold, magenta);
 2278:                  //textprintf(buf, font, 10, 0, white, "Angle: %f", fangle);
 2279:                  //textprintf(buf, font, 10, 20, white, "Angle: %f", angle);
 2280:                  
 2281:                  /*
 2282:          
 2283:                  //if(angle < 128 && angle > 64) angle = 64;
 2284:                  //else if(angle < 200) angle = 200;
 2285:                  if(fangle > 50) fangle = 50;
 2286:                  if(fangle < -64) fangle = -64;
 2287:                  */
 2288:          
 2289:                  //draw_sprite(transbuf, barrel, 10, 9);
 2290:                  //pivot_sprite(barrelbuf, barrel, 15, 13, 3, 2, itofix((int)fangle));
 2291:                  //textprintf(buf, font, 10, 30, white, "Dangle: %f", dangle);
 2292:    .             draw_sprite(hold, gunbg, offx, offy);
 2293:    .             pivot_sprite(hold, barrel, 22 + offx, 5 + offy, 13, 4, itofix((int)dangle));
 2294:    .             if(!occupied)
 2295:    .                 draw_sprite(hold, base, offx, offy - 1);
 2296:    .             else if(occupied && driver->comp == false)
 2297:    .                 draw_sprite(hold, baseo, offx, offy - 1);
 2298:    .             else if(occupied && driver->comp == true)
 2299:    .                 draw_sprite(hold, baseoe, offx, offy - 1);
 2300:    .             if(direction == RIGHT) {
 2301:    .                 draw_sprite(buf, hold, x, y);
 2302:                  }
 2303:    .             else {
 2304:    .                 draw_sprite_h_flip(buf, hold, x, y);
 2305:                  }
 2306:    .             drew = true;
 2307:              }
 2308:    .     }
 2309:          
 2310:    *     void jeep::update() {
 2311:              int tmpv;
 2312:          
 2313:    *         if(destroyed) return;
 2314:    *         if(occupied) {
 2315:    .             dokeys();
 2316:    .             if(me->ix > 40 || me->ix < -40) me->ix *= 0.9;
 2317:    .             if(me->iy > 0)
 2318:    .                 voice_set_frequency(engvoice, (fabs(me->ix) + me->iy) * 100 + 10000);
 2319:    .             else
 2320:    .                 voice_set_frequency(engvoice, fabs(me->ix) * 100 + 10000);
 2321:                  //if(voice_check(engstartvoice) != enginestart) dovoices();
 2322:              }
 2323:    *         if(damage > 150) {
 2324:    *             if(occupied) {
 2325:    .                 driver->me->iy -= 15;
 2326:    .                 driver->me->ix = me->ix * 0.4;
 2327:    .                 driver->health -= 50;
 2328:    .                 driver->injeep = NULL;
 2329:    .                 driver->invehicle = false;
 2330:    .                 occupied = false;
 2331:                  }
 2332:    *             if(direction == LEFT) {
 2333:    .                 myobj->obj = expl;
 2334:                  }
 2335:    .             else if(direction == RIGHT) {
 2336:    *                 myobj->obj = exp;
 2337:                  }
 2338:    *             addanimation(explosionanim, 16, me->x - 32, me->y - 32, true, 0, 1, 0);
 2339:    *             me->y -= 5;
 2340:    *             me->update();
 2341:    *             destroyvehiclerigidbody(me);
 2342:    *             me = NULL;
 2343:    *             destroyed = true;
 2344:    *             tmpv = allocate_voice(explode);
 2345:    *             voice_set_priority(tmpv, 255);
 2346:    *             voice_start(tmpv);
 2347:    *             release_voice(tmpv);
 2348:    *             deallocate_voice(engvoice);
 2349:    *             engvoice = NULL;
 2350:              }
 2351:    *     }
 2352:          
 2353:    *     void tank::getin(soldier *newdriver) {
 2354:              atom *a;
 2355:    *         driver = newdriver;
 2356:    *         if(destroyed) return;
 2357:    *         if(occupied == false) {
 2358:    *             occupied = true;
 2359:                  //driver->me->levels[me->atomlist[0]->level] = false;
 2360:    *             driver->me->dtmult = 0;
 2361:    *             driver->abody->dtmult = 0;
 2362:    *             if(voice_check(engstartvoice) != enginestart) dovoices();
 2363:    *             voice_start(engstartvoice);
 2364:    *             dopanvol(me->x, 0.5);
 2365:    *             voice_set_pan(engstartvoice, pan);
 2366:    *             voice_set_volume(engstartvoice, vol);
 2367:    *             release_voice(engstartvoice);
 2368:    *             engstarted = false;
 2369:    *             voice_set_position(engstartvoice, 0);
 2370:    *             if(driver->comp) {
 2371:    *                 a = me->atomlist[0];
 2372:    *                 for(int i = 0; i < me->mynumatoms; i++) {
 2373:    *                     a->levels[1] = true;
 2374:    *                     a->levels[5] = false;
 2375:    *                     a->levels[14] = false;
 2376:    *                     a->level = 12;
 2377:    *                     a++;
 2378:    *                 }
 2379:                  }
 2380:    *             else {
 2381:    *                 a = me->atomlist[0];
 2382:    *                 for(int i = 0; i < me->mynumatoms; i++) {
 2383:    *                     a->levels[1] = false;
 2384:    *                     a->levels[5] = true;
 2385:    *                     a->levels[13] = false;
 2386:    *                     a->level = 11;
 2387:    *                     a++;
 2388:    *                 }           
 2389:    *                 keyleft = &(key[KEY_A]);
 2390:    *                 keyright = &(key[KEY_D]);
 2391:    *                 keyup = &(key[KEY_W]);
 2392:    *                 keydown = &(key[KEY_S]);
 2393:                  }
 2394:                  //voice_ramp_volume(engvoice, 100, 255);
 2395:                  /*
 2396:                  if(direction == RIGHT)
 2397:                      myobj->obj = occ;
 2398:                  else
 2399:                      myobj->obj = occl;
 2400:                      */
 2401:              }
 2402:    *         else {
 2403:    .             driver->me->dtmult = 1;
 2404:    .             driver->abody->dtmult = 1;
 2405:    .             voice_ramp_volume(engvoice, 100, 0);
 2406:    .             engramp = 0;
 2407:    .             engdir = 0;
 2408:                  //engdir = -0.03;
 2409:    .             occupied = false;
 2410:    .             engstarted = false;
 2411:    .             a = me->atomlist[0];
 2412:    .             for(int i = 0; i < me->mynumatoms; i++) {
 2413:    .                 a->levels[1] = false;
 2414:    .                 a->levels[5] = false;
 2415:    .                 a->level = 7;
 2416:    .                 a++;
 2417:    .             }
 2418:                  /*
 2419:                  if(direction == RIGHT)
 2420:                      myobj->obj = unoc;
 2421:                  else
 2422:                      myobj->obj = unocl;
 2423:                      */
 2424:              }
 2425:    *     }
 2426:           
 2427:          
 2428:    *     void tank::draw() {
 2429:    *         if(destroyed) return;
 2430:          
 2431:              float offset;
 2432:              float tmp;
 2433:          
 2434:              //textprintf(buf, font, x - 200, 30, white, "Level: %i, levels[1]: %i", me->atomlist[0]->level, me->atomlist[0]->levels[1]);
 2435:          
 2436:    *         if(firing != 0) {
 2437:    *             if(firing == 20) {
 2438:    *                 barrel = tankbarrelanim[0];
 2439:    *                 firing = 0;
 2440:                  }
 2441:    *             else if(firing % 2 == 0) {
 2442:    *                 barrel = tankbarrelanim[int(firing * 0.5)];
 2443:    *                 firing++;
 2444:                  }
 2445:    *             else {
 2446:    *                 firing++;
 2447:                  }
 2448:          
 2449:    *             float offset = 18;
 2450:                  /*
 2451:                  if(firing == 10) {
 2452:                      addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -0.1, 1, 1);
 2453:                  }
 2454:                  else if(firing == 12) {
 2455:                      addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -0.4, 1, 5);
 2456:                  }
 2457:                  else if(firing == 14) {
 2458:                      addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -0.8, 1, 15);
 2459:                  }
 2460:                  else if(firing == 16) {
 2461:                      addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -1.2, 1, 25);
 2462:                  }
 2463:                  else if(firing == 18) {
 2464:                      addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -1.5, 1, 30);
 2465:                  }
 2466:                  */
 2467:    *             if(firing == 2) {
 2468:                      int tmpv;
 2469:    *                 tmpv = allocate_voice(tankfire);
 2470:    *                 voice_set_priority(tmpv, 255);
 2471:    *                 voice_start(tmpv);
 2472:    *                 dopanvol(me->x, 0.15);
 2473:    *                 voice_set_pan(tmpv, pan);
 2474:    *                 voice_set_volume(tmpv, vol);
 2475:    *                 release_voice(tmpv);
 2476:    *                 me->ix -= 500 * cos(barrelang * convk2);
 2477:    *                 me->gfric = 0.007;
 2478:                  }
 2479:    *             if(firing == 6) {
 2480:    *                 me->gfric = 0.001;
 2481:                  }
 2482:          
 2483:    *             if(firing == 10) {
 2484:    *                 addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -0.1, 1, 1);
 2485:    *                 addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -0.4, 1, 5);
 2486:                  }
 2487:    *             else if(firing == 11) {
 2488:    *                 addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -0.8, 1, 15);
 2489:                  }
 2490:    *             else if(firing == 12) {
 2491:    *                 addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -1.2, 1, 25);
 2492:    *                 addanimation(whiteanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, -1.5, 1, 30);
 2493:                  }
 2494:                  
 2495:    *             if(firing == 6) {
 2496:                      
 2497:                      //textprintf(buf, font, x - 200, 30, white, "Angle: %f", barrelang);
 2498:                      //textprintf(buf, font, x - 200, 50, white, "ca, sa: %f, %f", ca, sa);
 2499:                      //textprintf(buf, font, x - 200, 70, white, "me->ang: %f", me->ang * convk);
 2500:    *                 float bulletforce = 3;
 2501:    *                 offset = 25;
 2502:    *                 addbomb(x + offset * oca, y + offset * osa, bulletforce * oca, bulletforce * osa, driver->comp, shell);
 2503:    *                 offset -= 4;
 2504:                      /*
 2505:                      offset -= 4;
 2506:                      addanimation(redanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, 0, 1, 5);
 2507:                      offset += 5;
 2508:                      addanimation(yellowanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, 0, 1, 15);
 2509:                      offset += 5;
 2510:                      addanimation(yellowanim, 24, x + offset * ca - 15, y + offset * sa - 15, true, 0, 1, 25);
 2511:                      offset -= 15;
 2512:                      */
 2513:                  }
 2514:          
 2515:              }
 2516:          
 2517:    *         offset = 6.5;
 2518:    *         tmp = 3 - 0.6 * abs((barrelang + 64) * 0.08);
 2519:    *         if(tmp > 0) offset -= tmp;
 2520:    *         pivot_sprite(buf, barrel, x + offset * ca, y + offset * sa, 0, 4, itofix(barrelang + mk));
 2521:              /*
 2522:              float ca, sa, rca, rsa;
 2523:              float mk;
 2524:              float goalang;
 2525:              mk = me->ang * convk;
 2526:              ca = cos(me->ang);
 2527:              sa = sin(me->ang);
 2528:              rca = -sa;
 2529:              rsa = ca;
 2530:              cx = me->x - 0;
 2531:              cy = me->y - 0;
 2532:              if(barreldirection == RIGHT) {
 2533:                  x = cx + 29*ca - 8 * rca;
 2534:                  y = cy + 29*sa - 8 * rsa;
 2535:                  goalang = atan2(my - y, mx - x) * convk;
 2536:                  goalang -= mk;
 2537:                  if(goalang < -32) goalang = -32;
 2538:                  if(goalang > 0) goalang = 0;
 2539:                  if(barrelang < -32) barrelang = -32;
 2540:                  if(barrelang > 0) barrelang = 0;
 2541:              }
 2542:              else {
 2543:                  x = cx - 27*ca - 8 * rca;
 2544:                  y = cy - 27*sa - 8 * rsa;
 2545:                  goalang = atan2(my - y, mx - x) * convk;
 2546:                  goalang -= mk;
 2547:                  if(goalang > 0) goalang = -128;
 2548:                  if(goalang > -96) goalang = -96;
 2549:                  if(goalang < -128) goalang = -128;
 2550:                  if(barrelang > 0) barrelang = -128;
 2551:                  if(barrelang > -96) barrelang = -96;
 2552:                  if(barrelang < -128) barrelang = -128;
 2553:              }
 2554:              textprintf(buf, font, cx - 380, 0, white, "Angle: %f", mk);
 2555:              if(barrelang + barrelspeed < goalang) {
 2556:                  barrelang += barrelspeed;
 2557:              }
 2558:              else if(barrelang - barrelspeed > goalang) {
 2559:                  barrelang -= barrelspeed;
 2560:              }
 2561:              else {
 2562:                  barrelang = goalang;
 2563:              }
 2564:              
 2565:              if(barreldirection == RIGHT) pivot_sprite(buf, barrel, x, y, 0, 2, itofix(barrelang + mk));
 2566:              else pivot_sprite(buf, barrell, x, y, 0, 2, itofix(barrelang + mk));
 2567:          
 2568:              goalang = atan2(my - me->y, mx - me->x) * convk - mk;
 2569:              if(goalang < -64 && barreldirection == RIGHT) {
 2570:                  barreldirection = LEFT;
 2571:                  barrelang = -128 - barrelang;
 2572:              }
 2573:              else if(goalang > -64 && barreldirection == LEFT) {
 2574:                  barrelang = -128 - barrelang;
 2575:                  barreldirection = RIGHT;
 2576:              }
 2577:              */
 2578:    *     }
 2579:          
 2580:    *     void tank::dokeys() {
 2581:    *         if(destroyed) return;
 2582:              float appstrength;
 2583:              float dx, dy, d, dtx, dty;
 2584:              //float rx, ry;
 2585:    *         int motors[5] = {2, 6, 10, 14, 17};
 2586:              int i;
 2587:              atom *a;
 2588:          
 2589:              //offset = 0;
 2590:          
 2591:          
 2592:    *         if(!engstarted && voice_get_position(engstartvoice) >= 10000) {
 2593:    *             engdir = 0.02;
 2594:    *             engstarted = true;
 2595:              }
 2596:          
 2597:    *         tx = mx;
 2598:    *         ty = my;
 2599:          
 2600:    *         dx = me->atomlist[4]->x - me->atomlist[0]->x;
 2601:    *         dy = me->atomlist[4]->y - me->atomlist[0]->y;
 2602:              //rx = -dy;
 2603:              //ry = dx;
 2604:    *         d = sqrt(dx * dx + dy * dy);
 2605:    *         dx = dx / d;
 2606:    *         dy = dy / d;
 2607:          
 2608:    *         appstrength = strength * COMPFRAMES;
 2609:          
 2610:    *         dx *= appstrength * 0.05;
 2611:    *         dy *= appstrength * 0.05;
 2612:          
 2613:    *         dtx = tx - me->x;
 2614:    *         dty = ty - me->x;
 2615:          
 2616:          
 2617:    *         for(i = 0; i < 5; i++) {
 2618:    *             a = me->atomlist[motors[i]];
 2619:    *             if(a->y > path[(int)a->x] - 5) {
 2620:                      //me->ix += dx * 0.05;
 2621:                      //me->iy += dy * 0.05;
 2622:                      
 2623:    *                 if(*keyleft && !*keyright && !*keydown) {
 2624:    *                     me->ix -= dx;
 2625:    *                     me->iy -= dy;
 2626:                      }
 2627:    *                 else if(*keyright && !*keyleft && !*keydown) {
 2628:    *                     me->ix += dx;
 2629:    *                     me->iy += dy;
 2630:                      }
 2631:    *                 else {
 2632:                          //me->imult = 0;
 2633:          
 2634:    *                     if(me->ix < -dx) me->ix += dx;
 2635:    *                     else if(me->ix > dx) me->ix -= dx;
 2636:    *                     else {
 2637:    *                         me->ix = 0;
 2638:                          }
 2639:          
 2640:                          /*
 2641:                          if(me->iy < -dy) me->iy += dy;
 2642:                          else if(me->iy > dy) me->iy -= dy;
 2643:                          else {
 2644:                              me->iy = 0;
 2645:                          }
 2646:                          */
 2647:          
 2648:    *                     me->mx = 0;
 2649:                          //me->my = 0;
 2650:                          
 2651:    *                     if(a->ix < -dx) a->ix += dx;
 2652:    *                     else if(a->ix > dx) a->ix -= dx;
 2653:    *                     else {
 2654:    *                         a->ix = 0;
 2655:                          }
 2656:          
 2657:                          /*
 2658:                          if(a->iy < -dy) a->iy += dy;
 2659:                          else if(a->iy > dy) a->iy -= dy;
 2660:                          else {
 2661:                              a->iy = 0;
 2662:                          }
 2663:                          */
 2664:                          
 2665:    *                     a->mx = 0;
 2666:                          //a->my = 0;
 2667:                      }
 2668:                      /*
 2669:                      else {
 2670:                          dx *= 0.4;
 2671:                          dy *= 0.4;
 2672:                          if(me->ix > dx) {
 2673:                              me->ix -= dx;
 2674:                              if(me->iy > dy)
 2675:                                  me->iy -= dy;
 2676:                              else if(me->iy < -dy)
 2677:                                  me->iy += dy;
 2678:                              else
 2679:                                  me->iy = 0;
 2680:                          }
 2681:                          else if(me->ix < -dx) {
 2682:                              me->ix += dx;
 2683:                              if(me->iy > dy)
 2684:                                  me->iy -= dy;
 2685:                              else if(me->iy < -dy)
 2686:                                  me->iy += dy;
 2687:                              else
 2688:                                  me->iy = 0;
 2689:                          }
 2690:                          else {
 2691:                              me->ix = 0;
 2692:                              if(me->iy > dy)
 2693:                                  me->iy -= dy;
 2694:                              else if(me->iy < -dy)
 2695:                                  me->iy += dy;
 2696:                              else
 2697:                                  me->iy = 0;
 2698:                          }
 2699:                      }
 2700:                      */
 2701:                  }
 2702:    *         }
 2703:          
 2704:    *         if(fired <= 0 && ((occupied && !driver->comp && mouse_b & 1) || (occupied && driver->comp && *fire))) {
 2705:                  //if(voice_check(driver->gunvoice) != mgun) driver->dovoices();
 2706:                  //voice_ramp_volume(driver->gunvoice, 50, 255);
 2707:                  //voice_set_playmode(driver->gunvoice, PLAYMODE_LOOP);
 2708:                  //if(direction == RIGHT)
 2709:                  //addbullet(me->x + 28 * dx + 8 * rx, me->y + 28 * dy + 8 * ry, bulletforce * dx + 0.025 * me->ix, bulletforce * dy + 0.025 * me->iy, 0, 150, 1, 1, black);
 2710:                  //x + offset * ca, y + offset * sa
 2711:                  //addbomb(me->x + 15 * rx, me->y + 15 * ry, me->ix * 0.025, me->iy * 0.02, 0);
 2712:                  //addbullet(x + offset * ca, y + offset * sa, bulletforce * ca, bulletforce * sa, 0, 150, 1, 1, black);
 2713:                  //else
 2714:                      //addbullet(me->x - 28 * dx + 8 * rx, me->y - 28 * dy + 8 * ry, -bulletforce * dx + 0.025 * me->ix, -bulletforce * dy + 0.025 * me->iy, 0, 150, 1, 1, black);
 2715:                  //if(!isdamaged) myobj->obj = firing;
 2716:                  //else myobj->obj = damagedf;
 2717:                  //voice_start(driver->gunvoice);
 2718:    *             fired = 300;            
 2719:    *             firing = 1;
 2720:    *             oca = ca;
 2721:    *             osa = sa;
 2722:              }
 2723:    *         fired--;
 2724:          
 2725:          
 2726:              /*
 2727:              if(dtx < 0 && barreldirection == RIGHT) {
 2728:                  barreldirection = LEFT;
 2729:                  barrelang = -128 - barrelang;
 2730:              }
 2731:              else if(dtx > 0 && barreldirection == LEFT) {
 2732:                  barrelang = -128 - barrelang;
 2733:                  barreldirection = RIGHT;
 2734:              }
 2735:              */
 2736:          
 2737:                  /*
 2738:              if(me->y > path[(int)me->x] - 10 || me->y > path[(int)me->x + 10] - 10 || me->y > path[(int)me->x + 10] - 10) {
 2739:          
 2740:                  if(*keyleft && !*keyright && !*keydown) {
 2741:                      me->ix -= dx;
 2742:                      me->iy -= dy;
 2743:                      if(direction != LEFT) {
 2744:                          direction = LEFT;
 2745:                          //myobj->obj = occl;
 2746:                      }
 2747:                  }
 2748:                  else if(*keyright && !*keyleft && !*keydown) {
 2749:                      me->ix += dx;
 2750:                      me->iy += dy;
 2751:                      if(direction != RIGHT) {
 2752:                          direction = RIGHT;
 2753:                          //myobj->obj = occ;
 2754:                      }
 2755:                  }
 2756:                  else if(*keydown && !*keyleft && !*keyright) {
 2757:                      if(direction == LEFT) {
 2758:                          me->ix += dx;
 2759:                          me->iy += dy;
 2760:                      }
 2761:                      else if(direction == RIGHT) {
 2762:                          me->ix -= dx;
 2763:                          me->iy -= dy;
 2764:                      }
 2765:                  }
 2766:                  else {
 2767:                      dx *= 0.4;
 2768:                      dy *= 0.4;
 2769:                      if(me->ix > dx) {
 2770:                          me->ix -= dx;
 2771:                          if(me->iy > dy)
 2772:                              me->iy -= dy;
 2773:                          else if(me->iy < -dy)
 2774:                              me->iy += dy;
 2775:                          else
 2776:                              me->iy = 0;
 2777:                      }
 2778:                      else if(me->ix < -dx) {
 2779:                          me->ix += dx;
 2780:                          if(me->iy > dy)
 2781:                              me->iy -= dy;
 2782:                          else if(me->iy < -dy)
 2783:                              me->iy += dy;
 2784:                          else
 2785:                              me->iy = 0;
 2786:                      }
 2787:                      else {
 2788:                          me->ix = 0;
 2789:                          if(me->iy > dy)
 2790:                              me->iy -= dy;
 2791:                          else if(me->iy < -dy)
 2792:                              me->iy += dy;
 2793:                          else
 2794:                              me->iy = 0;
 2795:                      }
 2796:                  }
 2797:              }
 2798:              */
 2799:    *         speed = sqrt(me->ix * me->ix + me->iy * me->iy);
 2800:          
 2801:    *         int w = 128, h = 64;
 2802:          
 2803:              /*
 2804:              if(direction == RIGHT) {
 2805:                  blit(base, myobj->obj, 0, 0, 0, 0, w, h);
 2806:                  if(barreldirection == RIGHT)
 2807:                      draw_sprite(myobj->obj, gunu, 0, 0);
 2808:                  else
 2809:                      draw_sprite(myobj->obj, gunul, 0, 0);
 2810:              }
 2811:              else {
 2812:                  blit(basel, myobj->obj, 0, 0, 0, 0, w, h);
 2813:                  if(barreldirection == RIGHT)
 2814:                      draw_sprite(myobj->obj, gunu, 0, 0);
 2815:                  else
 2816:                      draw_sprite(myobj->obj, gunul, 0, 0);
 2817:              }
 2818:              */
 2819:    *     }
 2820:          
 2821:    *     void tank::update() {
 2822:              int tmpv;
 2823:          
 2824:    *         if(destroyed) return;
 2825:          
 2826:    *         if(engdir > 0) {
 2827:    *             engramp += engdir;
 2828:    *             if(engramp >= 1) {
 2829:    *                 engdir = 0;
 2830:    *                 engramp = 1;
 2831:                  }
 2832:              }
 2833:    *         else if(engdir < 0) {
 2834:    .             engramp += engdir;
 2835:    .             if(engramp <= 0) {
 2836:    .                 engdir = 0;
 2837:    .                 engramp = 0;
 2838:                  }
 2839:              }
 2840:          
 2841:    *         if(occupied) {
 2842:    *             ca = cos(me->ang);
 2843:    *             sa = sin(me->ang);
 2844:    *             rca = -sa;
 2845:    *             rsa = ca;
 2846:    *             ox = x;
 2847:    *             oy = y;
 2848:    *             x = me->x + 0.5 * ca - 4 * rca;
 2849:    *             y = me->y + 0.5 * sa - 4 * rsa;
 2850:    *             mk = me->ang;
 2851:          
 2852:    *             if(!driver->comp) {
 2853:    *                 tx = mx;
 2854:    *                 ty = my;
 2855:                  }
 2856:          
 2857:    *             goalang = atan2(ty - y, tx - x) - mk;
 2858:                  
 2859:    *             if(goalang > pi) goalang -= 2*pi;
 2860:                  //textprintf(buf, font, x - 200, 30, white, "Angle: %f", goalang * convk);
 2861:    *             if(goalang > pi * 0.5) goalang = -pi;
 2862:    *             else if(goalang > 0) goalang = 0;
 2863:    *             else if(goalang < -pi) goalang = -pi;
 2864:    *             ca = cos(goalang + mk);
 2865:    *             sa = sin(goalang + mk);
 2866:    *             goalang *= convk;
 2867:    *             mk *= convk;
 2868:              }
 2869:    *         else {
 2870:    *             ca = cos(me->ang);
 2871:    *             sa = sin(me->ang);
 2872:    *             rca = -sa;
 2873:    *             rsa = ca;
 2874:    *             ox = x;
 2875:    *             oy = y;
 2876:    *             x = me->x + 0.5 * ca - 4 * rca;
 2877:    *             y = me->y + 0.5 * sa - 4 * rsa;
 2878:    *             mk = me->ang;
 2879:    *             ca = cos(goalang * convk2 + mk);
 2880:    *             sa = sin(goalang * convk2 + mk);
 2881:    *             mk *= convk;
 2882:              }
 2883:          
 2884:    *         if(occupied) {
 2885:    *             barrelang = goalang;
 2886:    *             dokeys();
 2887:    *             if(speed > 200) {me->ix *= 0.9; me->iy *= 0.9;}
 2888:    *             if(drawframe % 15 == 0) {
 2889:    *                 if(me->iy > 0)
 2890:    *                     voice_set_frequency(engvoice, speed * 10 + 10000);
 2891:    *                 else
 2892:    *                     voice_set_frequency(engvoice, speed * 10 + 10000);
 2893:                      
 2894:    *                 dopanvol(me->x, 0.5);
 2895:    *                 voice_set_pan(engvoice, pan);
 2896:    *                 voice_set_volume(engvoice, vol * engramp);
 2897:                  }
 2898:                  //*/
 2899:                  //if(voice_check(engstartvoice) != enginestart) dovoices();
 2900:              }
 2901:              
 2902:              //textprintf(buf, font, me->x - 200, 60, white, "Tank damage: %f", damage);
 2903:    *         if(damage > 700 || me->y > waterlevel) {
 2904:    *             if(occupied) {
 2905:    *                 driver->me->iy -= 15;
 2906:    *                 driver->me->ix = me->ix * 0.06;
 2907:    *                 driver->health -= 50;
 2908:    *                 driver->intank = NULL;
 2909:    *                 driver->invehicle = false;
 2910:    *                 occupied = false;
 2911:    *                 driver->me->dtmult = 1;
 2912:    *                 driver->abody->dtmult = 1;
 2913:                  }
 2914:    *             addanimation(explosionanim, 16, me->x - 32, me->y - 32, true, 0, 1, 0);
 2915:    *             me->y -= 5;
 2916:    *             me->update();
 2917:    *             destroyvehiclerigidbody(me);
 2918:    *             me = NULL;
 2919:    *             destroyed = true;
 2920:    *             tmpv = allocate_voice(explode);
 2921:    *             voice_set_priority(tmpv, 255);
 2922:    *             voice_start(tmpv);
 2923:    *             release_voice(tmpv);
 2924:    *             deallocate_voice(engvoice);
 2925:    *             engvoice = NULL;
 2926:              }
 2927:    *     }
 2928:          
 2929:          //addanimation(explosionsmallanim, 15, me->x, me->y);
 2930:          
 2931:    .     void plane::dokeys() {
 2932:    .         if(destroyed) return;
 2933:          
 2934:    .         if(occupied) {          
 2935:                  //float dx, dy;
 2936:    .             float astrength = 100;
 2937:    .             float aforce = 3;
 2938:                  float app;
 2939:    .             float ang = me->ang * convk;
 2940:                  float goalang;
 2941:                  float ox, oy, od;
 2942:                  float dif;
 2943:          
 2944:    .             if(engstarted) {
 2945:    .                 if(*keyup && !*keydown && goalspeed < 40) {
 2946:    .                     goalspeed += 0.1;
 2947:                      }
 2948:    .                 else if(*keydown && !*keyup && goalspeed > 0) {
 2949:    .                     goalspeed -= 0.1;
 2950:                      }
 2951:                  }
 2952:          
 2953:    .             me->afric = FLUIDFRICTION;
 2954:                  
 2955:    .             if(me->y > path[(int)me->x] - 20) {
 2956:    .                 me->afric = 0.95;
 2957:    .                 me->ix *= 0.995;
 2958:                  }
 2959:          
 2960:    .             me->ix = 0;
 2961:    .             me->iy = 0;
 2962:          
 2963:    .             if(me->ix > 40) me->ix = 40;
 2964:    .             if(me->ix < -40) me->ix = -40;
 2965:          
 2966:    .             ox = mx - me->x;
 2967:    .             oy = my - me->y;
 2968:    .             od = sqrt(ox * ox + oy * oy);
 2969:    .             if(direction == RIGHT) {
 2970:    .                 goalang = atan2(oy, ox);
 2971:                  }
 2972:    .             else {
 2973:    .                 goalang = atan2(-oy, -ox);
 2974:                  }
 2975:                  
 2976:    .             if(!inturn) {
 2977:    .                 if(direction == RIGHT) {
 2978:    .                     me->ix += engspeed * dx;
 2979:    .                     me->iy += engspeed * dy;
 2980:                      }
 2981:    .                 else {
 2982:    .                     me->ix -= engspeed * dx;
 2983:    .                     me->iy -= engspeed * dy;
 2984:                      }
 2985:                  }
 2986:    .             else {
 2987:    .                 me->ix += engspeed * dx * cos(turnang);
 2988:    .                 me->iy += engspeed * dy * cos(turnang);
 2989:                  }
 2990:          
 2991:                  /*
 2992:                  if(!inturn) {
 2993:                      if(direction == RIGHT) {
 2994:                          if(dy < 0)
 2995:                              engspeed += 0.15 * dy;
 2996:                          else
 2997:                              engspeed += 0.3 * dy;
 2998:                      }
 2999:                      else {
 3000:                          if(dy < 0)
 3001:                              engspeed -= 0.3 * dy;
 3002:                          else
 3003:                              engspeed -= 0.15 * dy;
 3004:                      }
 3005:                  }
 3006:                  */
 3007:    .             if((!inturn && direction == RIGHT) || (inturn && direction == LEFT && turning < 0.5) || (inturn && direction == RIGHT && turning > 0.5)) {
 3008:    .                 if(dy < 0)
 3009:    .                     engspeed += 0.15 * dy;
 3010:    .                 else
 3011:    .                     engspeed += 0.3 * dy;
 3012:                  }
 3013:    .             else {
 3014:    .                 if(dy < 0)
 3015:    .                     engspeed -= 0.3 * dy;
 3016:    .                 else
 3017:    .                     engspeed -= 0.15 * dy;
 3018:                  }
 3019:          
 3020:                  //if(oy < 0) {
 3021:    .             if(engspeed < goalspeed)
 3022:    .                 engspeed += 0.1;
 3023:    .             else if(engspeed > goalspeed)
 3024:    .                 engspeed -= 0.1;
 3025:                  //} 
 3026:    .             engspeed *= 0.9995;
 3027:          
 3028:    .             speed = me->ix * dx + me->iy * dy;
 3029:          
 3030:    .             if(speed > 40) speed = 40;
 3031:    .             if(speed < -40) speed = -40;
 3032:          
 3033:    .             app = fabs(me->ix);
 3034:    .             if(oy > 0)
 3035:    .                 app = speed;
 3036:          
 3037:    .             if(speed > 0)
 3038:    .                 me->iy -= 1.75 * (app) * GRAVITY;
 3039:          
 3040:    .             if(me->ang > pi) me->ang -= 2*pi;
 3041:    .             if(me->ang < -pi) me->ang += 2*pi;
 3042:          
 3043:    .             dif = me->ang - goalang;
 3044:    .             if(fabs(dif * convk) > 128) dif = (pi - dif);
 3045:          
 3046:    .             me->ia = 0;
 3047:          
 3048:    .             if(fabs(dif) > 0.005 && engspeed > 5) {
 3049:    .                 if(dif < 0) {
 3050:    .                     me->ang += 0.008;
 3051:                      }
 3052:    .                 else {
 3053:    .                     me->ang -= 0.008;
 3054:                      }
 3055:                  }
 3056:    .             else if(engspeed > 5) {
 3057:    .                 me->ia = goalang;
 3058:                  }
 3059:          
 3060:    .             if(!inturn) {
 3061:    .                 if(direction == RIGHT ) {
 3062:    .                     if(engspeed < 38 && engspeed > 5) {
 3063:    .                         float add = 38 - engspeed;
 3064:    .                         if(ang < -64 || ang > 64) {
 3065:    .                             me->ang -= 0.001 * add;
 3066:                              }
 3067:    .                         else {
 3068:    .                             me->ang += 0.001 * add;
 3069:                              }
 3070:                          }
 3071:                      }
 3072:    .                 else {
 3073:    .                     if(engspeed < 38 && engspeed > 5) {
 3074:    .                         float add = 38 - engspeed;
 3075:    .                         if(ang < -64 || ang > 64) {
 3076:    .                             me->ang += 0.001 * add;
 3077:                              }
 3078:    .                         else {
 3079:    .                             me->ang -= 0.001 * add;
 3080:                              }
 3081:                          }
 3082:                      }
 3083:                  }
 3084:    .             if(engspeed < 38 && engspeed > 5) {
 3085:                      float dif;
 3086:    .                 dif = 38 - engspeed;
 3087:    .                 if(dif > 15) dif = 15;
 3088:    .                 me->y += 0.03 * dif;
 3089:                  }
 3090:    .             else if(engspeed < 5 && engspeed > 1) {         
 3091:                      float dif;
 3092:    .                 dif = engspeed;
 3093:    .                 me->y += 0.1125 * dif;
 3094:                  }
 3095:          
 3096:    .             speed = 2 * engspeed + 3 * sadd;
 3097:          
 3098:    .             if(!engstarted && voice_get_position(engstartvoice) >= 15000) {
 3099:    .                 voice_ramp_volume(engvoice, 300, 255);
 3100:    .                 engstarted = true;
 3101:                  }
 3102:          
 3103:    .             if(!noturn && !inturn && *keyleft && !*keyright) {
 3104:    .                 if(direction == RIGHT) {
 3105:    .                     direction = LEFT;
 3106:    .                     inturn = true;
 3107:                          float msx, cx;
 3108:    .                     mx = 2*me->x - mx;
 3109:    .                     msx = (mx - center->x + 600) * (2.0 / 3.0);
 3110:    .                     cx = mx - msx;
 3111:    .                     if(cx < 0) {
 3112:    .                         msx += cx;
 3113:                          }
 3114:    .                     else if(cx > buf->w - 800) {
 3115:    .                         msx += (cx - (buf->w - 800));
 3116:                              //msx -= cx - buf->w + 800;
 3117:                          }
 3118:    .                     position_mouse(msx, 2*me->y - my);
 3119:                      }
 3120:                  }
 3121:    .             else if(!noturn && !inturn && *keyright && !*keyleft) {
 3122:    .                 if(direction == LEFT) {
 3123:    .                     direction = RIGHT;
 3124:    .                     inturn = true;
 3125:                          float msx, cx;
 3126:    .                     mx = 2*me->x - mx;
 3127:    .                     msx = (mx - center->x + 600) * (2.0 / 3.0);
 3128:    .                     cx = mx - msx;
 3129:    .                     if(cx < 0) {
 3130:    .                         msx += cx;
 3131:                          }
 3132:    .                     else if(cx > buf->w - 800) {
 3133:    .                         msx += (cx - (buf->w - 800));
 3134:                              //msx -= cx - buf->w + 800;
 3135:                          }
 3136:    .                     position_mouse(msx, 2*me->y - my);
 3137:                      }
 3138:                  }
 3139:    .             else if(!inturn && !*keyleft && !*keyright)
 3140:    .                 noturn = false;
 3141:                  
 3142:    .             if(mouse_b & 2 && bfired <= 0 && !inturn) {
 3143:    .                 float bulletforce = 3;
 3144:    .                 if(direction == RIGHT)
 3145:    .                     addbomb(me->x + 15 * rx, me->y + 15 * ry, me->ix * 0.025, me->iy * 0.02, 0, bombbmp);
 3146:    .                 else
 3147:    .                     addbomb(me->x + 15 * rx, me->y + 15 * ry, me->ix * 0.025, me->iy * 0.02, 0, bombbmp);
 3148:    .                 play_sample(bombdrop, 255, 122, 1000, 0);
 3149:    .                 bfired = 150;
 3150:                      //bfired = 60;
 3151:                  }
 3152:    .             bfired--;
 3153:          
 3154:    .             if(mouse_b & 1 && fired <= 0 && !inturn) {
 3155:    .                 float bulletforce = 3;
 3156:    .                 if(voice_check(driver->gunvoice) != mgun) driver->dovoices();
 3157:    .                 voice_ramp_volume(driver->gunvoice, 50, 255);
 3158:    .                 voice_set_playmode(driver->gunvoice, PLAYMODE_LOOP);
 3159:    .                 if(direction == RIGHT)
 3160:    .                     addbullet(me->x + 28 * dx + 8 * rx, me->y + 28 * dy + 8 * ry, bulletforce * dx + 0.025 * me->ix, bulletforce * dy + 0.025 * me->iy, 0, 150, 1, 1, black, false);
 3161:    .                 else
 3162:    .                     addbullet(me->x - 28 * dx + 8 * rx, me->y - 28 * dy + 8 * ry, -bulletforce * dx + 0.025 * me->ix, -bulletforce * dy + 0.025 * me->iy, 0, 150, 1, 1, black, false);
 3163:    .                 if(!isdamaged) myobj->obj = firing;
 3164:    .                 else myobj->obj = damagedf;
 3165:    .                 voice_start(driver->gunvoice);
 3166:    .                 fired = 30;
 3167:                  }
 3168:    .             fired--;
 3169:    .             if(fired <= 5 && myobj->obj == firing) {
 3170:    .                 if(occupied) myobj->obj = occ;
 3171:    .                 else myobj->obj = unoc;
 3172:                  }
 3173:    .             else if(fired <= -5 && myobj->obj == damagedf) {
 3174:    .                 if(occupied) myobj->obj = damagedo;
 3175:    .                 else myobj->obj = damaged;
 3176:                  }
 3177:    .             if(fired < -5) {
 3178:    .                 voice_ramp_volume(driver->gunvoice, 50, 0);
 3179:                  }
 3180:              }
 3181:    .         else {
 3182:    .             me->afric = 0.95;
 3183:    .             if(me->y > path[(int)me->x] - 20) {
 3184:    .                 me->ix *= 0.995;
 3185:                  }
 3186:              }
 3187:    .     }
 3188:          
 3189:    .     void plane::update() {
 3190:              int tmpv;
 3191:          
 3192:    .         if(destroyed) return;
 3193:    .         dx = me->atomlist[3]->x - me->atomlist[0]->x;
 3194:    .         dy = me->atomlist[3]->y - me->atomlist[0]->y;
 3195:    .         rx = me->atomlist[1]->x - me->atomlist[0]->x;
 3196:    .         ry = me->atomlist[1]->y - me->atomlist[0]->y;
 3197:    .         dx *= 0.1;
 3198:    .         dy *= 0.1;
 3199:    .         rx *= 0.1;
 3200:    .         ry *= 0.1;
 3201:    .         dokeys();
 3202:          
 3203:    .         if(me->y > waterlevel) {
 3204:    .             me->iy -= 70 * GRAVITY;
 3205:              }
 3206:    .         else {
 3207:    .             me->iy += 70 * GRAVITY;
 3208:              }
 3209:          
 3210:    .         if(inturn) {        
 3211:    .             turning += 0.002;
 3212:    .             if(turning > 1) turning = 1;
 3213:    .             if(direction == LEFT) {
 3214:    .                 turnang = turning * pi;
 3215:                  }
 3216:    .             else if(direction == RIGHT) {
 3217:    .                 turnang = turning * pi + pi;
 3218:                  }
 3219:    .             tcos = cos(turnang);
 3220:    .             me->turning = tcos;
 3221:    .             if(turning >= 1) {
 3222:    .                 turning = 0;
 3223:    .                 inturn = false;
 3224:                  }
 3225:              }
 3226:          
 3227:    .         if(occupied) {
 3228:                  //if(me->ix * me->ix + me->iy * me->iy > 1600) me->ix *= 0.9;
 3229:                  //if(me->iy > 0)
 3230:                      //voice_set_frequency(engvoice, (speed + me->iy) * 100 + 10000);
 3231:                  //else
 3232:          
 3233:    .             voice_set_frequency(engvoice, speed * 100 + 1000);
 3234:          
 3235:                  //if(voice_check(engstartvoice) != propstart) dovoices();
 3236:              }
 3237:    .         else {
 3238:    .             engspeed -= 0.1;
 3239:    .             if(engspeed < 0) engspeed = 0;
 3240:    .             goalspeed = 0;
 3241:              }
 3242:    .         if(me->y >= waterlevel - 5) {
 3243:    .             if(occupied) {
 3244:    .                 driver->me->iy -= 1;
 3245:    .                 driver->me->ix = me->ix * 0.1;
 3246:                      //driver->health -= 50;
 3247:    .                 driver->inplane = NULL;
 3248:    .                 driver->invehicle = false;
 3249:    .                 occupied = false;
 3250:                  }
 3251:    .             if(direction == LEFT) {
 3252:    .                 myobj->obj = expl;
 3253:                  }
 3254:    .             else if(direction == RIGHT) {
 3255:    .                 myobj->obj = exp;
 3256:                  }
 3257:                  /*
 3258:                  addtrailanim(me->atomlist[7], explosionsmallanim, 24, 10, rand() % 10, 1500 + rand() % 1500, -2, 5, false, 1);
 3259:                  addtrailanim(me->atomlist[7], explosionsmallanim, 24, 10, rand() % 10, 1500 + rand() % 1500, -2, 5, false, 1);
 3260:                  addtrailanim(me->atomlist[10], explosionsmallanim, 24, 10, rand() % 10, 1500 + rand() % 1500, -2, 5, false, 1);
 3261:                  addtrailanim(me->atomlist[10], explosionsmallanim, 24, 10, rand() % 10, 1500 + rand() % 1500, -2, 5, false, 1);
 3262:                  addanimation(explosionanim, 16, me->x - 32, me->y - 32, true, 0, 1, 0);
 3263:                  */
 3264:    .             me->y -= 5;
 3265:    .             me->update();
 3266:    .             me->gmult = 70;
 3267:    .             me->ix *= 0.3;
 3268:    .             me->iy *= 0.3;
 3269:    .             destroyvehiclerigidbody(me);
 3270:    .             me = NULL;
 3271:    .             destroyed = true;
 3272:    .             tmpv = allocate_voice(gurgle);
 3273:    .             voice_set_priority(tmpv, 255);
 3274:    .             voice_start(tmpv);
 3275:    .             release_voice(tmpv);
 3276:    .             deallocate_voice(engvoice);
 3277:    .             engvoice = NULL;
 3278:              }
 3279:    .         else if(damage > 50) {
 3280:    .             if(occupied) {
 3281:    .                 driver->me->iy -= 5;
 3282:    .                 driver->me->ix = me->ix * 0.3;
 3283:    .                 driver->health -= 50;
 3284:    .                 driver->inplane = NULL;
 3285:    .                 driver->invehicle = false;
 3286:    .                 occupied = false;
 3287:                  }
 3288:    .             if(direction == LEFT) {
 3289:    .                 myobj->obj = expl;
 3290:                  }
 3291:    .             else if(direction == RIGHT) {
 3292:    .                 myobj->obj = exp;
 3293:                  }
 3294:    .             addtrailanim(me->atomlist[7], explosionsmallanim, 24, 10, rand() % 10, 1500 + rand() % 1500, -2, 5, false, 1);
 3295:    .             addtrailanim(me->atomlist[7], explosionsmallanim, 24, 10, rand() % 10, 1500 + rand() % 1500, -2, 5, false, 1);
 3296:    .             addtrailanim(me->atomlist[10], explosionsmallanim, 24, 10, rand() % 10, 1500 + rand() % 1500, -2, 5, false, 1);
 3297:    .             addtrailanim(me->atomlist[10], explosionsmallanim, 24, 10, rand() % 10, 1500 + rand() % 1500, -2, 5, false, 1);
 3298:    .             addanimation(explosionanim, 16, me->x - 32, me->y - 32, true, 0, 1, 0);
 3299:    .             me->y -= 5;
 3300:    .             me->update();
 3301:    .             me->gmult = 70;
 3302:    .             destroyvehiclerigidbody(me);
 3303:    .             me = NULL;
 3304:    .             destroyed = true;
 3305:    .             tmpv = allocate_voice(explode);
 3306:    .             voice_set_priority(tmpv, 255);
 3307:    .             voice_start(tmpv);
 3308:    .             release_voice(tmpv);
 3309:    .             deallocate_voice(engvoice);
 3310:    .             engvoice = NULL;
 3311:              }
 3312:    .         else if(damage > 25 && isdamaged == false) {
 3313:    .             isdamaged = true;
 3314:    .             if(occupied) myobj->obj = damagedo;
 3315:    .             else myobj->obj = damaged;
 3316:              }
 3317:    .         if(!destroyed && isdamaged && dispframe) addanimation(smokeanim, 24, me->polylistx[1] - 15 + 3*rx, me->polylisty[1] - 15 + 3*ry, true, -1, 1, 20);//addanimation(smokeanim, 24, me->polylistx[1] - 15 - 3*dx*tcos + 3*rx, me->polylisty[1] - 15 - 3*dy*tcos + 3*ry, true, -1, 1, 20);
 3318:    .     }
 3319:          
 3320:          struct compsoldier {
 3321:              soldier *me;
 3322:          
 3323:              volatile char goleft;
 3324:              volatile char goright;
 3325:              volatile char goup;
 3326:              volatile char godown;
 3327:              volatile char getin;
 3328:              bool fire;
 3329:              float personality;
 3330:              
 3331:              //BEHAVIORS:
 3332:          
 3333:              //Hunt
 3334:              bool hunt;
 3335:          
 3336:              //Patrol
 3337:              bool patrol;
 3338:              int patrolzonel;
 3339:              int patrolzoner;
 3340:              bool patroldirection;
 3341:          
 3342:              //Trippatrol (Patrols until sights enemy)
 3343:              bool trippatrol;
 3344:          
 3345:              //Wait
 3346:              bool wait;
 3347:          
 3348:              //AA Gunner
 3349:              bool aagunner;
 3350:              aagun *mygun;
 3351:          
 3352:              //Tank driver
 3353:              bool tankdriver;
 3354:              bool intank;
 3355:              tank *mytank;
 3356:          
 3357:    *         compsoldier() {
 3358:    *             reset();
 3359:    *         }
 3360:          
 3361:    *         void reset() {
 3362:    *             me = NULL;
 3363:    *             goleft = goright = goup = godown = getin = false;
 3364:    *             fire = false;
 3365:    *             patrol = false;
 3366:    *             hunt = false;
 3367:    *             intank = false;
 3368:    *             trippatrol = false;
 3369:    *             wait = false;
 3370:    *             personality = (rand() % 100) / 100.0;
 3371:    *         }
 3372:          
 3373:    *         void init(soldier *s) {
 3374:    *             personality = (rand() % 100) / 100.0;
 3375:    *             me = s;
 3376:    *             me->keyleft = &goleft;
 3377:    *             me->keyright = &goright;
 3378:    *             me->keyup = &goup;
 3379:    *             me->keydown = &godown;
 3380:    *             me->keygetin = &getin;
 3381:    *             me->fire = &fire;
 3382:    *             me->comp = true;
 3383:    *         }
 3384:          
 3385:    *         void dohunt() {
 3386:    *             hunt = true;
 3387:    *         }
 3388:          
 3389:    *         void dopatrol(int l, int r) {
 3390:    *             hunt = false;
 3391:    *             patrol = true;
 3392:    *             patrolzonel = l;
 3393:    *             patrolzoner = r;
 3394:    *             patroldirection = RIGHT;
 3395:    *         }
 3396:          
 3397:              void dotrippatrol(int l, int r) {
 3398:                  hunt = false;
 3399:                  patrol = true;
 3400:                  trippatrol = true;
 3401:                  patrolzonel = l;
 3402:                  patrolzoner = r;
 3403:                  patroldirection = RIGHT;
 3404:              }
 3405:          
 3406:    *         void dowait() {
 3407:    *             wait = true;
 3408:    *             hunt = false;
 3409:    *         }
 3410:          
 3411:    .         void doaagunner(aagun *a) {
 3412:    .             mygun = a;
 3413:    .             aagunner = true;
 3414:    .         }
 3415:          
 3416:    *         void dotankdriver(tank *t) {
 3417:    *             mytank = t;
 3418:    *             tankdriver = true;
 3419:    *             intank = false;
 3420:    *         }
 3421:          
 3422:    *         void update() {
 3423:    *             if(me->dead) return;
 3424:          
 3425:    *             if(drawframe % 100 == 0)        
 3426:    *                 personality = (rand() % 100) / 100.0;
 3427:          
 3428:                  /*
 3429:                  if(human->dead) {
 3430:                      goleft = goright = goup = godown = fire = false;
 3431:                      me->dokeys();
 3432:                      return;
 3433:                  }
 3434:                  */
 3435:                  float tx, ty;
 3436:                  float ex, ey;
 3437:                  float eix, eiy;
 3438:                  float x, y;
 3439:                  bool edead;
 3440:    *             x = me->me->x;
 3441:    *             y = me->me->y;
 3442:    *             fire = false;
 3443:    *             goleft = goright = 0;
 3444:    *             if(!human->dead) {
 3445:    *                 ex = human->me->x;
 3446:    *                 ey = human->me->y;
 3447:    *                 eix = human->me->ix;
 3448:    *                 eiy = human->me->ix;
 3449:    *                 edead = false;
 3450:                  }
 3451:    *             else {
 3452:    *                 ex = 0;
 3453:    *                 eix = 0;
 3454:    *                 ey = eiy = 400;
 3455:    *                 edead = true;
 3456:                  }
 3457:          
 3458:    *             if(hunt) {
 3459:                      int offdist;
 3460:    *                 tx = ex;
 3461:    *                 if(intank) ty = ey - fabs(x - ex) * 0.15;
 3462:    *                 else ty = ey - 8;
 3463:    *                 if(intank) offdist = 250;
 3464:    *                 else offdist = 50;
 3465:    *                 offdist = (0.5 + 1.5 * personality) * offdist;
 3466:          
 3467:    *                 if(me->tx < me->me->x - offdist) {
 3468:    *                     goleft = true;
 3469:    *                     goright = false;
 3470:    *                     if(patrol) patroldirection = LEFT;
 3471:                      }
 3472:    *                 else if(me->tx > me->me->x + offdist) {
 3473:    .                     goright = true;
 3474:    .                     goleft = false;
 3475:    .                     if(patrol) patroldirection = RIGHT;
 3476:                      }
 3477:    .                 else {
 3478:    *                     goleft = goright = false;
 3479:                      }
 3480:    *                 if((fabs(tx - x) <= offdist + 20 || fabs(tx - x) < 200 + 200 * personality) && (!intank || mytank->fired <= 0)) {
 3481:    *                     if(intank) ty += 60 * (rand() % 100) * 0.01 - 30;
 3482:    *                     else ty += 30 * (rand() % 100) * 0.01 - 15;
 3483:    *                     fire = true;
 3484:                      }
 3485:    *                 else fire = false;
 3486:                  }
 3487:    *             if(patrol) {
 3488:    *                 if(abs(x - ex) < 200) {
 3489:    .                     hunt = true;
 3490:    .                     if(trippatrol) {
 3491:    .                         patrol = false;
 3492:    .                         trippatrol = false;
 3493:                          }
 3494:                      }
 3495:    .                 else if(abs(x - ex) > 300) hunt = false;
 3496:          
 3497:    *                 if(x >= patrolzoner) {
 3498:    *                     patroldirection = LEFT;
 3499:    *                     goright = false;
 3500:                      }
 3501:    *                 else if(x <= patrolzonel) {
 3502:    *                     patroldirection = RIGHT;
 3503:    *                     goleft = false;
 3504:                      }
 3505:    *                 if(!hunt && patroldirection == RIGHT) {
 3506:    *                     goright = true;
 3507:    *                     goleft = false;
 3508:    *                     if(intank) {
 3509:    .                         tx = x + 5;
 3510:    .                         ty = y;
 3511:                          }
 3512:    .                     else {
 3513:    *                         tx = x + 5;
 3514:    *                         ty = y - 8;
 3515:                          }
 3516:    *                     fire = false;
 3517:                      }
 3518:    *                 else if(!hunt && patroldirection == LEFT) {
 3519:    *                     goleft = true;
 3520:    *                     goright = false;
 3521:    *                     if(intank) {
 3522:    .                         tx = x - 5;
 3523:    .                         ty = y;
 3524:                          }
 3525:    .                     else {
 3526:    *                         tx = x - 5;
 3527:    *                         ty = y - 8;
 3528:                          }
 3529:    *                     fire = false;
 3530:                      }
 3531:                  }
 3532:    *             if(wait) {          
 3533:    *                 if(abs(x - ex) < 600) {
 3534:    .                     hunt = true;
 3535:    .                     wait = false;
 3536:                      }
 3537:                  }
 3538:    *             if(aagunner && !edead) {
 3539:    .                 if(!me->invehicle) {
 3540:    .                     if(mygun->x  + 26 < x - 5)
 3541:    .                         goleft = true;
 3542:    .                     else if(mygun->x + 26> x + 5)
 3543:    .                         goright = true;
 3544:    .                     else {
 3545:    .                         mygun->getin(me);
 3546:    .                         me->invehicle = true;
 3547:    .                         me->inaagun = mygun;
 3548:    .                         mygun->fire = &fire;
 3549:                          }
 3550:                      }
 3551:    .                 else {
 3552:                          float dx, dy, dist;
 3553:    .                     dx = ex - x;
 3554:    .                     dy = ey - y;
 3555:    .                     dy *= 1;
 3556:    .                     if(dx > 500) dx = 500;
 3557:    .                     else if(dx < -500) dx = -500;
 3558:    .                     dist = (dx * dx + dy * dy);
 3559:                          //fprintf(debug, "dist = %f, (%f, %f)\n", dist, dx, dy);
 3560:    .                     if(eix > 0) {
 3561:    .                         mygun->tx = ex + 0.0008 * dist;
 3562:                              //mygun->tx = ex + 0.85 * fabs(y - ey) + 0.0005 * fabs(x - ex) * fabs(y - ey);
 3563:                          }
 3564:    .                     else {
 3565:    .                         mygun->tx = ex - 0.0008 * dist;
 3566:                              //mygun->tx = ex - 0.85 * fabs(y - ey) - 0.0005 * fabs(x - ex) * fabs(y - ey);
 3567:                          }
 3568:    .                     mygun->ty = ey;
 3569:                          //mygun->ty += 0.5 * dist;
 3570:          
 3571:                          //mygun->ty = ey + 15 * eiy;
 3572:    .                     if(fabs(x - ex) < 500 && fabs(mygun->fangle - mygun->angle) < 1) {
 3573:    .                         fire = true;
 3574:                          }
 3575:                      }
 3576:                  }
 3577:    *             if(tankdriver) {
 3578:    *                 if(mytank->destroyed) {
 3579:    *                     tankdriver = false;
 3580:    *                     hunt = true;
 3581:    *                     intank = false;
 3582:                      }
 3583:    *                 else {
 3584:    *                     if(!me->invehicle) {
 3585:    *                         intank = false;
 3586:    *                         if(mytank->x  + 26 < x - 5)
 3587:    *                             goleft = true;
 3588:    *                         else if(mytank->x + 26> x + 5)
 3589:    *                             goright = true;
 3590:    *                         else {
 3591:    *                             mytank->getin(me);
 3592:    *                             me->invehicle = true;
 3593:    *                             me->intank = mytank;
 3594:    *                             mytank->fire = &fire;
 3595:    *                             mytank->keyleft = &goleft;
 3596:    *                             mytank->keyright = &goright;
 3597:    *                             mytank->keyup = &goup;
 3598:    *                             mytank->keydown = &godown;
 3599:    *                             intank = true;
 3600:                              }
 3601:                          }
 3602:    *                     else {                  
 3603:    *                         mytank->tx = tx;
 3604:    *                         mytank->ty = ty;
 3605:                          }
 3606:    *                     if(0) {
 3607:    .                         tx = ex;
 3608:    .                         ty = ey - 8;
 3609:    .                         ty = ey - fabs(x - ex) * 0.2;
 3610:    .                         if(me->tx < me->me->x - 250) {
 3611:    .                             goleft = true;
 3612:    .                             goright = false;
 3613:    .                             if(patrol) patroldirection = LEFT;
 3614:                              }
 3615:    .                         else if(me->tx > me->me->x + 250) {
 3616:    .                             goright = true;
 3617:    .                             goleft = false;
 3618:    .                             if(patrol) patroldirection = RIGHT;
 3619:                              }
 3620:    .                         else {
 3621:    .                             goleft = goright = false;
 3622:                              }
 3623:    .                         mytank->tx = tx;
 3624:    .                         mytank->ty = ty;
 3625:    .                         if(fabs(tx - x) < 300) fire = true;
 3626:    .                         else fire = false;
 3627:                          }
 3628:                      }
 3629:                  }
 3630:          
 3631:    *             me->tx = tx;
 3632:    *             me->ty = ty;
 3633:    *         }
 3634:          };
 3635:          
 3636:    *     compsoldier compsoldiers[MAXCOMPSOLDIERS];
 3637:          int numcompsoldiers;
 3638:          
 3639:    *     void updatesoldiers() {
 3640:              int i;
 3641:              soldier *s;
 3642:              
 3643:    *         s = &(soldiers[0]);
 3644:    *         for(i = 0; i < numsoldiers; i++) {
 3645:    *             s->update();
 3646:    *             s++;
 3647:    *         }
 3648:    *     }
 3649:          
 3650:    *     void updatecompsoldiers() {
 3651:              int i;
 3652:              compsoldier *s;
 3653:              
 3654:    *         s = &(compsoldiers[0]);
 3655:    *         for(i = 0; i < numcompsoldiers; i++) {
 3656:    *             s->update();
 3657:    *             s++;
 3658:    *         }
 3659:    *     }
 3660:          
 3661:    *     void drawsoldiers() {
 3662:              int i;
 3663:              soldier *s;
 3664:              
 3665:    *         s = &(soldiers[0]);
 3666:    *         for(i = 0; i < numsoldiers; i++) {
 3667:    *             s->draw();
 3668:    *             s++;
 3669:    *         }
 3670:    *     }
 3671:          
 3672:    *     void erasesoldiers() {
 3673:              int i;
 3674:              soldier *s;
 3675:              
 3676:    *         s = &(soldiers[0]);
 3677:    *         for(i = 0; i < numsoldiers; i++) {
 3678:    *             s->erase();
 3679:    *             s++;
 3680:    *         }
 3681:    *     }
 3682:          
 3683:    *     soldier *addsoldier() {
 3684:              soldier *s;
 3685:    *         s = &(soldiers[numsoldiers]);
 3686:    *         numsoldiers++;
 3687:    *         return s;
 3688:    *     }
 3689:          
 3690:    *     compsoldier *addcompsoldier() {
 3691:              compsoldier *c;
 3692:    *         c = &(compsoldiers[numcompsoldiers]);
 3693:    *         numcompsoldiers++;
 3694:    *         return c;
 3695:    *     }
 3696:          
 3697:    *     compsoldier *addenemysoldier(float x, float y) {
 3698:              soldier *s;
 3699:              atom *a;
 3700:              compsoldier *c;
 3701:    *         settmplevels();
 3702:    *         tmplevels[1] = false;
 3703:    *         tmplevels[4] = false;
 3704:    *         tmplevels[5] = false;
 3705:    *         tmplevels[6] = false;
 3706:    *         tmplevels[7] = false;
 3707:    *         tmplevels[12] = false;
 3708:    *         tmplevels[14] = false;
 3709:    *         s = addsoldier();
 3710:    *         a = addatom(x, y, tmplevels, 5);
 3711:    *         c = addcompsoldier();
 3712:    *         a->rmdt = 0.23;
 3713:    *         s->comp = true;
 3714:    *         s->init(a);
 3715:    *         c->init(s);
 3716:    *         return c;
 3717:    *     }
 3718:          
 3719:          void initlevel();
 3720:          
 3721:    *     void init_graphics() {
 3722:    *         allegro_init();
 3723:    *         set_color_depth(16);
 3724:    *         if(!WINDOWED) set_gfx_mode(GFX_AUTODETECT, 800, 600, 0, 0);
 3725:    *         else set_gfx_mode(GFX_AUTODETECT_WINDOWED, 300, 300, 0, 0);
 3726:    *         install_timer();
 3727:    *         install_keyboard();
 3728:    *         install_mouse();
 3729:    *         reserve_voices(64, 1);
 3730:    *         set_volume_per_voice(5);
 3731:    *         install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, "moo");
 3732:    *         set_volume(100, 65);
 3733:              //set_volume(50, 50);
 3734:    *         set_alpha_blender();
 3735:    *         set_color_conversion(COLORCONV_EXPAND_256);
 3736:    *         set_alpha_blender();
 3737:    *     }
 3738:          
 3739:    *     void readpath(char *file) {
 3740:    *          ifstream iff;
 3741:    *          iff.open(file);
 3742:               
 3743:    *          int read = 0, last = -1, pos = 0;
 3744:          
 3745:               int tmp;
 3746:    *          iff >> tmp;
 3747:    *          while(pos < tmp) {
 3748:    *              last = read;
 3749:    *              iff >> read;
 3750:    *              path[pos] = (600.0 / 480.0) * read;
 3751:    *              debrislev[pos] = (600.0 / 480.0) * read - 7;
 3752:    *              pos++;
 3753:    *          }
 3754:          
 3755:    *          iff.close();
 3756:    *     }
 3757:          
 3758:    *     void updatebombs() {
 3759:              bomb *b;
 3760:              int i;
 3761:    *         b = &(bombs[0]);
 3762:    *         for(i = 0; i < numbombs; i++) {
 3763:    *             if(b->on) {
 3764:    *                 b->update();
 3765:                  }
 3766:    *             b++;
 3767:    *         }
 3768:    *     }
 3769:          
 3770:    *     void update() {
 3771:              bullet *b;
 3772:              int i;
 3773:          
 3774:    *         updaterigidbodies();
 3775:    *         physics_update();
 3776:    *         updatetrailanims();
 3777:    *         updatecompsoldiers();
 3778:    *         updatesoldiers();
 3779:    *         updateaaguns();
 3780:    *         updatejeeps();
 3781:    *         updatetanks();
 3782:    *         updateplanes();
 3783:    *         updatebombs();
 3784:    *         b = &(bullets[0]);
 3785:    *         for(i = 0; i < MAXBULLETS; i++) {
 3786:    *             b->update();
 3787:    *             b++;
 3788:    *         }
 3789:    *     }
 3790:          
 3791:    *     void drawdebris() {
 3792:              debrisitem *d;
 3793:              int i;
 3794:    *         d = &(debris[0]);
 3795:    *         for(i = 0; i < MAXDEBRIS; i++) {
 3796:    *             if(d->on) {
 3797:    *                 d->draw();
 3798:                  }
 3799:    *             d++;
 3800:    *         }
 3801:    *     }
 3802:          
 3803:    *     void erasedebris() {
 3804:              debrisitem *d;
 3805:              int i;
 3806:    *         d = &(debris[0]);
 3807:    *         for(i = 0; i < MAXDEBRIS; i++) {
 3808:    *             if(d->on) {
 3809:    *                 d->erase();
 3810:                  }
 3811:    *             d++;
 3812:    *         }
 3813:    *     }
 3814:          
 3815:    *     void drawbombs() {
 3816:              bomb *b;
 3817:              int i;
 3818:    *         b = &(bombs[0]);
 3819:    *         for(i = 0; i < numbombs; i++) {
 3820:    *             if(b->on) {
 3821:    *                 b->draw();
 3822:                  }
 3823:    *             b++;
 3824:    *         }
 3825:    *     }
 3826:          
 3827:    *     void erasebombs() {
 3828:              bomb *b;
 3829:              int i;
 3830:    *         b = &(bombs[0]);
 3831:    *         for(i = 0; i < numbombs; i++) {
 3832:    *             if(b->on) {
 3833:    *                 b->erase();
 3834:                  }
 3835:    *             b++;
 3836:    *         }
 3837:    *     }
 3838:          
 3839:    *     void drawbullets() {
 3840:              bullet *b;
 3841:              int i;
 3842:    *         b = &(bullets[0]);
 3843:    *         for(i = 0; i < MAXBULLETS; i++) {
 3844:    *             if(b->life > 0) {
 3845:    *                 b->draw();
 3846:                  }
 3847:    *             b++;
 3848:    *         }
 3849:    *     }
 3850:          
 3851:    *     void erasebullets() {
 3852:              bullet *b;
 3853:              int i;
 3854:    *         b = &(bullets[0]);
 3855:    *         for(i = 0; i < MAXBULLETS; i++) {
 3856:    *             if(b->life > 0) {
 3857:    *                 b->erase();
 3858:                  }
 3859:    *             b++;
 3860:    *         }
 3861:    *     }
 3862:          
 3863:          //MAINDRAW
 3864:          
 3865:    *     void draw() {
 3866:              float cx, mdx, mdy;
 3867:          
 3868:    *         if(center->fixed) {
 3869:    *             if(mouse_x < 100) {
 3870:    *                 center->x -= (100 - mouse_x) * 0.2;
 3871:                  }
 3872:    *             else if(mouse_x > 700) {
 3873:    .                 center->x += (mouse_x - 700) * 0.2;
 3874:                  }
 3875:              }
 3876:          
 3877:              //cx = (400 + mouse_x) * 0.5 + center->x - 800;//((center->x - 400) + (mouse_x - 400)) * 0.5;
 3878:    *         cx = 0.5 * mouse_x + center->x - 600;
 3879:    *         if(cx < 0) cx = 0;
 3880:    *         if(cx > ground->w - 800) cx = ground->w - 800;
 3881:    *         lx = cx;
 3882:    *         rx = cx + 800;
 3883:    *         mx = mouse_x + cx;
 3884:    *         my = mouse_y - mousebmp->h / 2;
 3885:    *         mdx = mx - mousebmp->w / 2;
 3886:    *         mdy = my - mousebmp->h / 2;
 3887:              
 3888:              //textprintf(buf, font, cx + 10, 10, white, "X: %f", center->x);
 3889:              //textprintf(buf, font, cx + 10, 20, white, "Y: %f", center->y);
 3890:    *         textprintf(buf, font, cx + 10, 10, white, "Health: %f", human->health);
 3891:              //textprintf(buf, font, cx + 10, 30, white, "Jeep damage: %f", jeep1.damage);
 3892:          
 3893:    *         drawaaguns();
 3894:    *         drawatoms();
 3895:    *         drawlinks();
 3896:    *         drawpolys();
 3897:    *         drawtanks();
 3898:    *         drawplanes();
 3899:    *         drawbullets();
 3900:    *         drawbombs();
 3901:    *         drawdebris();
 3902:    *         drawsoldiers();
 3903:    *         drawanimations();
 3904:          
 3905:              //if(!human->invehicle)
 3906:    *         draw_sprite(buf, mousebmp, mdx, mdy);
 3907:          
 3908:    *         vsync();
 3909:              
 3910:              
 3911:    *         if(!WINDOWED) blit(buf, screen, cx, 0, 0, 0, 800, 600);
 3912:    *         else blit(buf, screen, center->x - 150, center->y - 150, 0, 0, 300, 300);
 3913:              //blit(buf, screen, center->x - 50, center->y - 50, 0, 0, 100, 100);
 3914:    *         screencenterx = cx + 400;
 3915:              //fprintf(debug, "I JUST SET: %i\n", screencenterx);
 3916:          
 3917:          
 3918:              //blit(buf, screen, 1800, 400, 0, 0, 200, 200);
 3919:          
 3920:    *         blit(bg, buf, cx, 10, cx, 10, 200, 10);
 3921:          
 3922:    *         eraseatoms();
 3923:    *         eraselinks();
 3924:    *         erasepolys();
 3925:    *         eraseaaguns();
 3926:    *         eraseplanes();
 3927:    *         erasebullets();
 3928:    *         erasetanks();
 3929:    *         erasebombs();
 3930:    *         erasedebris();
 3931:    *         erasesoldiers();
 3932:    *         eraseanimations();
 3933:    *         blit(bg, buf, mdx, mdy, mdx, mdy, mousebmp->w, mousebmp->h);
 3934:    *     }
 3935:          
 3936:          bool boxadded;
 3937:          
 3938:    *     void dokeys() {
 3939:    *         if(key[KEY_R]) {
 3940:                  int i;
 3941:    *             reset();
 3942:    *             destroy_bitmap(ground);
 3943:    *             destroy_bitmap(buf);
 3944:    *             destroy_bitmap(sky);
 3945:    *             destroy_bitmap(bg);
 3946:    *             ground = buf = sky = bg = NULL;
 3947:    *             for(i = 0; i < numjeeps; i++) {
 3948:    *                 jeeps[i].killvoices();
 3949:    *                 jeeps[i].reset();
 3950:                      //jeeps[i].init();
 3951:    *             }
 3952:    *             numjeeps = 0;
 3953:    *             for(i = 0; i < numtanks; i++) {
 3954:    *                 tanks[i].killvoices();
 3955:    *                 tanks[i].reset();
 3956:    *             }
 3957:    *             numtanks = 0;
 3958:    *             for(i = 0; i < numplanes; i++) {
 3959:    .                 planes[i].killvoices();
 3960:    .                 planes[i].reset();
 3961:                      //planes[i].init();
 3962:    .             }
 3963:    *             numplanes = 0;
 3964:    *             for(i = 0; i < MAXBULLETS; i++) {
 3965:    *                 bullets[i].life = 0;
 3966:    *                 bullets[i].update();
 3967:    *                 bullets[i].init();
 3968:    *             }
 3969:    *             for(i = 0; i < MAXBOMBS; i++) {
 3970:    *                 bombs[i].on = false;
 3971:    *                 bombs[i].init();
 3972:    *             }
 3973:    *             numbombs = 0;
 3974:    *             for(i = 0; i < MAXDEBRIS; i++) {
 3975:    *                 debris[i].on = false;
 3976:    *                 debris[i].init();
 3977:    *             }
 3978:    *             for(i = 0; i < numsoldiers; i++) {
 3979:    *                 soldiers[i].killvoices();
 3980:    *                 soldiers[i].reset();
 3981:    *             }
 3982:    *             numsoldiers = 0;
 3983:    *             for(i = 0; i < numcompsoldiers; i++) {
 3984:    *                 compsoldiers[i].reset();
 3985:    *             }
 3986:    *             numcompsoldiers = 0;
 3987:    *             for(i = 0; i < numanimations; i++) {
 3988:    .                 animations[i].reset();
 3989:    .             }
 3990:    *             numanimations = 0;
 3991:    *             for(i = 0; i < MAXTRAILANIMS; i++) {
 3992:    *                 trailanims[i].reset();
 3993:    *             }
 3994:    *             numtrailanims = 0;
 3995:    *             for(i = 0; i < numaaguns; i++) {
 3996:    .                 aaguns[i].reset();
 3997:    .             }
 3998:    *             numaaguns = 0;
 3999:    *             initlevel();
 4000:    *             while(key[KEY_R]) ;
 4001:              }
 4002:    *         if(key[KEY_B] && !boxadded) {
 4003:    .             addbox();
 4004:    .             boxadded = true;
 4005:              }
 4006:    .         else if(!key[KEY_B])
 4007:    *             boxadded = false;
 4008:    *     }
 4009:          
 4010:    *     void initvars() {
 4011:              int i;
 4012:              BITMAP *tmp;
 4013:    *         boxadded = false;
 4014:    *         mousebmp = load_bitmap("target.pcx", NULL);
 4015:    *         black = makecol16(0,0,0);
 4016:    *         green = makecol16(0,255,0);
 4017:    *         white = makecol16(255,255,255);
 4018:    *         magenta = makecol16(255, 0, 255);
 4019:    *         gray = makecol16(122, 122, 122);
 4020:    *         yellow = makecol16(220, 220, 0);
 4021:    *         convk = 128.0 / pi;
 4022:    *         convk2 = pi / 128.0;
 4023:    *         COMPFRAMES = 6;
 4024:    *         srand(time(NULL));
 4025:    *         settmplevels();
 4026:    *         mgun = load_sample("mgun.wav");
 4027:    *         bombdrop = load_sample("bombdrop.wav");
 4028:    *         aagunfire = load_sample("aagun.wav");
 4029:    *         tankfire = load_sample("tankfire.wav");
 4030:    *         gurgle = load_sample("gurgle.wav");
 4031:    *         splash = load_sample("splash.wav");
 4032:    *         engine = load_sample("engine.wav");
 4033:    *         enginestart = load_sample("enginestart.wav");
 4034:    *         prop = load_sample("prop.wav");
 4035:    *         propstart = load_sample("propstart.wav");
 4036:    *         death1 = load_sample("death1.wav");
 4037:              //play_sample(mgun, 255, 122, 1000, 0);
 4038:    *         explode = load_sample("explodelarge.wav");
 4039:    *         explodesmall = load_sample("explodesm.wav");
 4040:    *         music = load_midi("lev1.mid");
 4041:              //play_midi(music, true);
 4042:    *         numanimations = 0;
 4043:    *         numtrailanims = 0;
 4044:    *         numbombs = 0;
 4045:              jeep *j;
 4046:    *         for(i = 0; i < MAXJEEPS; i++) {
 4047:    *             j = &(jeeps[i]);
 4048:    *             j->unoc = load_bitmap("jeepu.pcx", NULL);
 4049:    *             j->unocl = load_bitmap("jeepul.pcx", NULL);
 4050:    *             j->occ = load_bitmap("jeepo.pcx", NULL);
 4051:    *             j->occl = load_bitmap("jeepol.pcx", NULL);
 4052:    *             j->exp = load_bitmap("jeepd.pcx", NULL);
 4053:    *             j->expl = load_bitmap("jeepdl.pcx", NULL);
 4054:    *         }
 4055:          
 4056:              tank *t;
 4057:    *         for(i = 0; i < MAXTANKS; i++) {
 4058:    *             t = &(tanks[i]);
 4059:    *             t->base = load_bitmap("tanku.pcx", NULL);
 4060:                  //t->basel = load_bitmap("tankul.pcx", NULL);
 4061:                  //t->gunu = load_bitmap("tankgun.pcx", NULL);
 4062:                  //t->gunul = load_bitmap("tankgunl.pcx", NULL);
 4063:                  //t->guno = load_b itmap("tankgun.pcx", NULL);
 4064:                  //t->gunol = load_bitmap("tankgunl.pcx", NULL);
 4065:          
 4066:                  //t->barrel = load_bitmap("tankbarrel.pcx", NULL);
 4067:          
 4068:                  //t->barrell = load_bitmap("tankbarrell.pcx", NULL);
 4069:          
 4070:                  //t->occ = load_bitmap("jeepo.pcx", NULL);
 4071:                  //t->occl = load_bitmap("jeepol.pcx", NULL);
 4072:                  //t->exp = load_bitmap("jeepd.pcx", NULL);
 4073:                  //t->expl = load_bitmap("jeepdl.pcx", NULL);
 4074:    *         }
 4075:              
 4076:              plane *p;
 4077:    *         for(i = 0; i < MAXPLANES; i++) {
 4078:    *             p = &(planes[i]);
 4079:    *             p->unoc = load_bitmap("planeu.pcx", NULL);
 4080:    *             p->occ = load_bitmap("planeo.pcx", NULL);
 4081:    *             p->firing = load_bitmap("planef.pcx", NULL);
 4082:    *             p->exp = load_bitmap("planed.pcx", NULL);
 4083:    *             p->expl = load_bitmap("planedl.pcx", NULL);
 4084:    *             p->damaged = load_bitmap("planeh.pcx", NULL);
 4085:    *             p->damagedo = load_bitmap("planeoh.pcx", NULL);
 4086:    *             p->damagedf = load_bitmap("planehf.pcx", NULL);
 4087:    *         }
 4088:          
 4089:              aagun *a;
 4090:    *         for(i = 0; i < MAXAAGUNS; i++) {
 4091:    *             a = &(aaguns[i]);
 4092:    *             a->barrel = load_bitmap("aagunbarrel.pcx", NULL);
 4093:    *             a->gunbg = load_bitmap("aagunbg.pcx", NULL);
 4094:    *             a->base = load_bitmap("aagunbase.pcx", NULL);
 4095:    *             a->baseo = load_bitmap("aagunbaseo.pcx", NULL);
 4096:    *             a->baseoe = load_bitmap("aagunbaseoe.pcx", NULL);
 4097:    *         }
 4098:    *         debris1 = load_bitmap("debris1.tga", NULL);
 4099:    *         debriso1 = load_bitmap("debriso1.tga", NULL);
 4100:    *         grounddebris1 = load_bitmap("grounddebris1.pcx", NULL);
 4101:    *         debrisr[0] = load_bitmap("debrisr1.tga", NULL);
 4102:    *         debrisr[1] = load_bitmap("debrisr2.tga", NULL);
 4103:    *         debrisr[2] = load_bitmap("debrisr3.tga", NULL);
 4104:    *         debrisr[3] = load_bitmap("debrisr4.tga", NULL);
 4105:    *         debrisrm[0] = load_bitmap("debrisrm1.tga", NULL);
 4106:    *         debrisrm[1] = load_bitmap("debrisrm2.tga", NULL);
 4107:    *         debrisrm[2] = load_bitmap("debrisrm3.tga", NULL);
 4108:    *         debrisrm[3] = load_bitmap("debrisrm4.tga", NULL);
 4109:    *         scorch = load_bitmap("scorch.tga", NULL);
 4110:    *         bombbmp = load_bitmap("bomb.pcx", NULL);
 4111:    *         shell = load_bitmap("shell.pcx", NULL);
 4112:    *         tmp = load_bitmap("explosion.tga", NULL);
 4113:              int x, y;
 4114:          
 4115:    *         for(x = 0; x < 4; x++) {
 4116:    *             for(y = 0; y < 4; y++) {
 4117:    *                 explosionanim[x + y*4] = create_bitmap_ex(32, 64, 64);
 4118:    *                 blit(tmp, explosionanim[x + y*4], x * 64, y * 64, 0, 0, 64, 64);
 4119:    *             }
 4120:    *         }
 4121:          
 4122:    *         destroy_bitmap(tmp);
 4123:    *         tmp = load_bitmap("explosionsmall.pcx", NULL);
 4124:    *         for(x = 0; x < 24; x++) {
 4125:    *             explosionsmallanim[x] = create_bitmap(9, 9);
 4126:    *             blit(tmp, explosionsmallanim[x], x * 9, 0, 0, 0, 9, 9);
 4127:    *         }
 4128:          
 4129:    *         destroy_bitmap(tmp);
 4130:    *         tmp = load_bitmap("tankbarrel.pcx", NULL);
 4131:    *         for(y = 0; y < 10; y++) {
 4132:    *             tankbarrelanim[y] = create_bitmap(17, 8);
 4133:    *             blit(tmp, tankbarrelanim[y], 0, y * 8, 0, 0, 17, 8);
 4134:    *         }
 4135:          
 4136:    *         destroy_bitmap(tmp);
 4137:    *         tmp = load_bitmap("smoke.tga", NULL);
 4138:    *         for(x = 0; x < 24; x++) {
 4139:    *             smokeanim[x] = create_bitmap_ex(32, 30, 30);
 4140:    *             blit(tmp, smokeanim[x], x * 30, 0, 0, 0, 30, 30);
 4141:    *         }
 4142:          
 4143:    *         destroy_bitmap(tmp);
 4144:    *         tmp = load_bitmap("redpart.tga", NULL);
 4145:    *         for(x = 0; x < 24; x++) {
 4146:    *             redanim[x] = create_bitmap_ex(32, 30, 30);
 4147:    *             blit(tmp, redanim[x], x * 30, 0, 0, 0, 30, 30);
 4148:    *         }
 4149:          
 4150:    *         destroy_bitmap(tmp);
 4151:    *         tmp = load_bitmap("yellowpart.tga", NULL);
 4152:    *         for(x = 0; x < 24; x++) {
 4153:    *             yellowanim[x] = create_bitmap_ex(32, 30, 30);
 4154:    *             blit(tmp, yellowanim[x], x * 30, 0, 0, 0, 30, 30);
 4155:    *         }
 4156:          
 4157:    *         destroy_bitmap(tmp);
 4158:    *         tmp = load_bitmap("whitepart.tga", NULL);
 4159:    *         for(x = 0; x < 24; x++) {
 4160:    *             whiteanim[x] = create_bitmap_ex(32, 30, 30);
 4161:    *             blit(tmp, whiteanim[x], x * 30, 0, 0, 0, 30, 30);
 4162:    *         }
 4163:          
 4164:    *         destroy_bitmap(tmp);
 4165:    *         tmp = load_bitmap("splash.pcx", NULL);
 4166:    *         for(x = 0; x < 6; x++) {
 4167:    *             splashanim[x] = create_bitmap(9, 4);
 4168:    *             blit(tmp, splashanim[x], x * 9, 0, 0, 0, 9, 4);
 4169:    *         }
 4170:          
 4171:    *         destroy_bitmap(tmp);
 4172:    *     }
 4173:          
 4174:    *     void initlevel() {
 4175:    *         if(level == 1) {
 4176:    *             ground = load_bitmap("lev1.pcx", NULL);
 4177:    *             readpath("lev1.pat");
 4178:    *             waterlevel = 600;
 4179:              }
 4180:    *         else if(level == 2) {
 4181:    .             ground = load_bitmap("lev2.pcx", NULL);
 4182:    .             readpath("lev2.pat");
 4183:    .             waterlevel = 524;
 4184:              }
 4185:    *         sky = load_bitmap("sky.pcx", NULL);
 4186:    *         bg = create_bitmap(ground->w, ground->h);
 4187:    *         buf = create_bitmap(ground->w, ground->h);
 4188:    *         draw_sprite(bg, sky, 0, 0);
 4189:    *         draw_sprite(bg, ground, 0, 0);
 4190:    *         draw_sprite(buf, bg, 0, 0);
 4191:    *         settmplevels();
 4192:    *         tmplevels[1] = false;
 4193:    *         tmplevels[0] = false;
 4194:    *         tmplevels[6] = false;
 4195:    *         tmplevels[7] = false;
 4196:              //addobject("building.pcx", 100, 234, true, tmplevels, 2, 1);
 4197:          
 4198:              //tmplevels[2] = false;
 4199:          
 4200:              //exptemp = create_bitmap_ex(32, 
 4201:          
 4202:              compsoldier *e;
 4203:              aagun *a;
 4204:              tank *t;
 4205:              
 4206:    *         if(level == 1) {
 4207:    *             bool madness = false;
 4208:    *             if(!madness && 1 && 0) {
 4209:    .                 e = addenemysoldier(1100, 400);
 4210:    .                 e->dohunt();
 4211:    .                 e = addenemysoldier(1130, 400);
 4212:    .                 e->dohunt();
 4213:    .                 e = addenemysoldier(1160, 400);
 4214:    .                 e->dohunt();
 4215:    .                 e = addenemysoldier(1190, 400);
 4216:    .                 e->dohunt();
 4217:                  }
 4218:          
 4219:    *             e = addenemysoldier(1900, 400);
 4220:    *             t = addtank(1900, 412, true);
 4221:    *             e->dotankdriver(t);
 4222:    *             e->dowait();
 4223:          
 4224:                  ///*
 4225:    *             t = addtank(2000, 412, true);
 4226:    *             e = addenemysoldier(2100, 400);
 4227:    *             e->dotankdriver(t);
 4228:                  //e->dowait();
 4229:    *             e->dohunt();
 4230:                  
 4231:    *             t = addtank(2100, 412, true);
 4232:    *             e = addenemysoldier(2100, 400);
 4233:    *             e->dotankdriver(t);
 4234:                  //e->dowait();
 4235:    *             e->dohunt();
 4236:                  
 4237:    *             t = addtank(2200, 412, true);
 4238:    *             e = addenemysoldier(2100, 400);
 4239:    *             e->dotankdriver(t);
 4240:                  //e->dowait();
 4241:    *             e->dohunt();
 4242:                  
 4243:    *             t = addtank(1700, 412, true);
 4244:    *             e = addenemysoldier(2100, 400);
 4245:    *             e->dotankdriver(t);
 4246:                  //e->dowait();
 4247:    *             e->dohunt();
 4248:                  
 4249:    *             t = addtank(1800, 412, true);
 4250:    *             e = addenemysoldier(2100, 400);
 4251:    *             e->dotankdriver(t);
 4252:                  //e->dowait();
 4253:    *             e->dohunt();
 4254:                  
 4255:    *             t = addtank(1900, 412, true);
 4256:    *             e = addenemysoldier(2100, 400);
 4257:    *             e->dotankdriver(t);
 4258:                  //e->dowait();
 4259:    *             e->dohunt();
 4260:                  //*/
 4261:                  
 4262:                  /*
 4263:                  e = addenemysoldier(500, 400);
 4264:                  e = addenemysoldier(510, 400);
 4265:                  e = addenemysoldier(520, 400);
 4266:                  e = addenemysoldier(530, 400);  
 4267:                  */
 4268:          
 4269:                  ///*
 4270:    *             e = addenemysoldier(1670, 444);
 4271:    *             e->dopatrol(1670, 1760);
 4272:    *             e = addenemysoldier(1770, 444);
 4273:    *             e->dopatrol(1770, 1940);
 4274:    *             e = addenemysoldier(1950, 473);
 4275:    *             e->dopatrol(1950, 2320);
 4276:    *             e = addenemysoldier(1950, 473);
 4277:    *             e->dopatrol(1950, 2020);
 4278:    *             e = addenemysoldier(1950, 473);
 4279:    *             e->dopatrol(2200, 2320);
 4280:    *             e = addenemysoldier(1950, 473);
 4281:    *             e->dopatrol(2630, 2720);
 4282:                  //e = addenemysoldier(1950, 473);
 4283:                  //e->dopatrol(2730, 2820);
 4284:    *             e = addenemysoldier(2050, 473);
 4285:    *             e->dopatrol(2920, 2990);
 4286:                  //*/
 4287:          
 4288:    *             settmplevels();
 4289:    *             tmplevels[1] = false;
 4290:    *             tmplevels[0] = false;
 4291:    *             tmplevels[6] = false;
 4292:    *             tmplevels[7] = false;
 4293:    *             addobject("building.pcx", "buildingt.tga", 2157, 320, true, tmplevels, 2, 1);
 4294:    *             if(!madness) {
 4295:    *                 addobject("building.pcx", "buildingt.tga", 2640, 020, true, tmplevels, 2, 1.015);
 4296:                  }
 4297:    *             else {
 4298:    .                 addobject("building.pcx", "buildingt.tga", 2740, 020, true, tmplevels, 2, 1.015);
 4299:                  }
 4300:    *             if(madness) {
 4301:                      aagun *a;
 4302:                      //addplane(10, 502);
 4303:    .                 addtank(10, 302, false);
 4304:    .                 a = addaagun(1680, 412);
 4305:    .                 e = addenemysoldier(1680, 473);
 4306:    .                 e->doaagunner(a);
 4307:    .                 a = addaagun(1960, 442);
 4308:    .                 e = addenemysoldier(1960, 423);
 4309:    .                 e->doaagunner(a);
 4310:    .                 a = addaagun(2725, 183);
 4311:    .                 e = addenemysoldier(2700, 170);
 4312:    .                 e->doaagunner(a);
 4313:                  }
 4314:    .             else {
 4315:    *                 addtank(150, 412, false);
 4316:    *                 addjeep(300, 402);
 4317:                      //addplane(225, 412);
 4318:                      //settmplevels();
 4319:                      //addobject("tankcomp.pcx", NULL, 450, 390, 0, tmplevels, 2, 1);
 4320:                  }
 4321:    *             settmplevels();
 4322:    *             tmplevels[1] = false;
 4323:    *             tmplevels[4] = false;
 4324:    *             tmplevels[3] = false;
 4325:    *             tmplevels[7] = false;
 4326:    *             tmplevels[10] = true;
 4327:    *             tmplevels[11] = false;
 4328:    *             if(!madness) {
 4329:    *                 center = addatom(400, 440, tmplevels, 1);
 4330:                  }
 4331:    *             else {
 4332:    .                 center = addatom(10, 440, tmplevels, 1);
 4333:                  }
 4334:    *             center->rmdt = 0.23;
 4335:    *             human = addsoldier();
 4336:    *             human->init(center);
 4337:              }
 4338:    *         else if(level == 2) {
 4339:    .             settmplevels();
 4340:    .             tmplevels[1] = false;
 4341:    .             tmplevels[0] = false;
 4342:    .             tmplevels[6] = false;
 4343:    .             tmplevels[7] = false;
 4344:    .             addobject("building.pcx", "buildingt.tga", 2000, 254, true, tmplevels, 2, 1);
 4345:                  //addobject("building.pcx", "buildingt.tga", 2300, 254, true, tmplevels, 2, 1);
 4346:                  //addobject("building2.pcx", "building2t.tga", 2000, 219, true, tmplevels, 2, 1);
 4347:                  //addobject("building3.pcx", "building3t.tga", 2000, 262, true, tmplevels, 2, 1);
 4348:                  //addobject("building4.pcx", "building4t.tga", 2000, 253, true, tmplevels, 2, 1);
 4349:                  //addobject("building4.pcx", NULL, 2300, 253, true, tmplevels, 2, 1);
 4350:    .             e = addenemysoldier(1900, 500);
 4351:    .             e->dopatrol(1900, 2000);
 4352:    .             e = addenemysoldier(1900, 500);
 4353:    .             e->dopatrol(2300, 2500);
 4354:          
 4355:                  //e = addenemysoldier(1900, 500);
 4356:                  //t = addtank(1900, 400, true);
 4357:                  //e->dotankdriver(t);
 4358:                  //e->dowait();
 4359:          
 4360:          
 4361:                  /*
 4362:                  a = addaagun(580, 447);
 4363:                  e = addenemysoldier(450, 450);
 4364:                  e->doaagunner(a);
 4365:                  */
 4366:                  ///*
 4367:    .             a = addaagun(1876, 419);
 4368:    .             e = addenemysoldier(1900, 500);
 4369:    .             e->doaagunner(a);
 4370:                  //*/
 4371:          
 4372:                  /*
 4373:                  e = addenemysoldier(1900, 500);
 4374:                  e->dopatrol(1950, 2450);
 4375:                  e = addenemysoldier(1900, 500);
 4376:                  e->dopatrol(2000, 2100);
 4377:                  e = addenemysoldier(1900, 500);
 4378:                  e->dopatrol(2200, 2250);
 4379:                  e = addenemysoldier(1900, 500);
 4380:                  e->dopatrol(2250, 2500);
 4381:                  */
 4382:    .             addplane(300, 573);
 4383:                  //addtank(300, 450);
 4384:    .             settmplevels();
 4385:    .             tmplevels[1] = false;
 4386:    .             tmplevels[4] = false;
 4387:    .             tmplevels[3] = false;
 4388:    .             tmplevels[7] = false;
 4389:    .             tmplevels[10] = true;
 4390:    .             tmplevels[11] = true;
 4391:    .             center = addatom(400, 485, tmplevels, 1);
 4392:    .             center->rmdt = 0.23;
 4393:    .             human = addsoldier();
 4394:    .             human->init(center);
 4395:              }
 4396:    *     }
 4397:          
 4398:    *     int main() {
 4399:    *         int compframe = 0;//, frame = 0;
 4400:    *         bool boxadded = false;
 4401:          
 4402:    *         level = 1;
 4403:          
 4404:    *         init_graphics();
 4405:    *         initvars();
 4406:    *         physics_initvars();
 4407:    *         physics_initialize();
 4408:    *         initlevel();
 4409:          
 4410:    *         frame = 0;
 4411:    *         drawframe = 0;
 4412:    *         dispframe = false;
 4413:          
 4414:              //time_t timestart, timenow;
 4415:              //timestart = time(&timenow);
 4416:          
 4417:    *         while(!key[KEY_Q] && !key[KEY_ESC]) {
 4418:    *             compframe++;
 4419:          
 4420:    *             if(compframe == COMPFRAMES) {
 4421:    *                 draw();
 4422:    *                 compframe = 0;
 4423:                      //frame++;
 4424:    *                 drawframe++;
 4425:    *                 dispframe = true;
 4426:    *                 if(numsplashes > 0 && drawframe % 10 == 0) numsplashes--;
 4427:                  }
 4428:          
 4429:    *             update();
 4430:          
 4431:    *             frame++;
 4432:    *             dispframe = false;
 4433:                  //fprintf(debug, "frame = %i\n", frame);
 4434:          
 4435:                  /*
 4436:                  if(time(&timenow) - timestart >= 1) {
 4437:                      textprintf(buf, font, 10, 50, white, "Framerate: %i", frame);
 4438:                      frame = 0;
 4439:                      timestart = time(&timenow);
 4440:                  }
 4441:                  */
 4442:          
 4443:    *             dokeys();
 4444:    *         }
 4445:    *         return 1;
 4446:    *     }
 4447:          
 4447:          END_OF_MAIN();
 4448:    *     

Source file: h:\programming\gen2\physics.cpp

  Line Covered  Source
----------------------
    1:          #include <math.h>
    2:          #include <allegro.h>
    3:          #include <stdlib.h>
    4:          #include <stdio.h>
    5:          #include <time.h>
    6:          #include <string.h>
    7:          
    8:          
    9:          
   10:          
   11:          
   12:          
   13:          //                  **HELPER FUNCTIONS**
   14:          
   15:          extern FILE *debug;
   16:          
   17:    .     void message(char *s) {
   18:              //alert(s, NULL, NULL, "OK", NULL, NULL, NULL);
   19:    .         fprintf(debug, s);
   20:    .     }
   21:          
   22:          
   23:          
   24:          
   25:          
   26:          
   27:          //                  **PHYSICS**
   28:          
   29:          #define REPULSESTRENGTH .25
   30:          #define LINKSTRENGTH .31
   31:          #define FLUIDFRICTION 0.9995
   32:          #define FRICTION 0.0005
   33:          #define GRAVITY .008
   34:          #define MAXBOXX 304
   35:          #define MAXBOXY 64
   36:          #define MAXATOMS 10000
   37:          #define MAXLINKS 80000
   38:          #define MAXPOLYS 10000
   39:          #define MAXOBJECTS 100
   40:          #define MAXRIGIDBODIES 10
   41:          #define MAXRATOMS 300
   42:          #define MAXDEBRIS 5000
   43:          #define MAXLEVELS 20
   44:          #define BPMULT 1.04
   45:          #define DELTAT 1
   46:          #define PIXW 10
   47:          
   48:          //#define MVTDRAIN 0.005
   49:          //#define DEADZONE 0.5
   50:          
   51:          float DIAGRL, DIAGBP, STRBP;
   52:          int COMPFRAMES;
   53:          
   54:          int green, black, white, magenta, gray, yellow;
   55:          
   56:          extern BITMAP *buf;
   57:          extern BITMAP *bg;
   58:          extern BITMAP *sky;
   59:          extern BITMAP *scorch;
   60:          extern BITMAP *debris1;
   61:          extern BITMAP *debriso1;
   62:          extern BITMAP *debrisr[4];
   63:          extern BITMAP *debrisrm[4];
   64:          extern BITMAP *explosionsmallanim[24];
   65:          extern BITMAP *splashanim[6];
   66:          BITMAP *thold;
   67:          BITMAP *tmp;
   68:          
   69:          extern SAMPLE *explodesmall;
   70:          extern SAMPLE *explode;
   71:          extern SAMPLE *splash;
   72:          extern int numsplashes;
   73:          
   74:          extern int path[4000];
   75:          extern int debrislev[4000];
   76:          
   77:          extern float lx, rx;
   78:          
   79:          int expc;
   80:          extern int waterlevel;
   81:          
   82:          extern float convk;
   83:          
   84:          int forcetable_repulse_x[20][20];
   85:          int forcetable_repulse_y[20][20];
   86:          
   87:          typedef struct atom atom;
   88:          typedef struct link link;
   89:          typedef struct poly poly;
   90:          typedef struct debrisitem debrisitem;
   91:          typedef struct rigidbody rigidbody;
   92:          
   93:          void adddebris(atom *, bool);
   94:          void addtrailanim(atom *a, BITMAP **anim, int frames, int mod, int modoff, int life, float dy, int rand, bool trans, int delay);
   95:          void addanimation(BITMAP **newframes, int newnumframes, int newx, int newy, bool trans, float dy, int delay, int rand);
   96:          void dopanvol(float x, float k);
   97:          
   98:          extern int pan, vol;
   99:          
  100:          struct atom {
  101:              float x, y;
  102:              float ox, oy;
  103:              float ix, iy;
  104:              float oix, oiy;
  105:              float mx, my;
  106:              float mass;
  107:              float rmdt;
  108:              int bx, by;
  109:              link *l[8];
  110:              int lc;
  111:              int color;
  112:              bool draw;
  113:              bool fixed;
  114:              bool on;
  115:              bool debris;
  116:              bool transdeb;
  117:              bool nullstate;
  118:              debrisitem *d;
  119:              rigidbody *r;
  120:              BITMAP *bmp;
  121:              float mvt;
  122:              int st;
  123:              float *damage;
  124:              float dmult;
  125:              float dtmult;
  126:              bool draw2;
  127:              int life;
  128:          
  129:              int level;
  130:              bool levels[MAXLEVELS];
  131:          
  132:    *         atom() {
  133:    *             init();
  134:    *         }
  135:          
  136:    *         void init() {
  137:                  int i;
  138:          
  139:    *             st = 0;
  140:    *             x = y = 400;
  141:    *             ox = oy = 400;
  142:    *             ix = iy = 0;
  143:    *             oix = oiy = 20;
  144:    *             mass = 1;
  145:    *             rmdt = 1;
  146:    *             bx = by = 0;
  147:    *             mx = my = 0;
  148:    *             l[0] = l[1] = l[2] = l[3] = l[4] = l[5] = l[6] = l[7] = NULL;
  149:    *             for(i = 1; i < MAXLEVELS; i++) {
  150:    *                 levels[i] = true;
  151:    *             }
  152:    *             levels[0] = false;
  153:    *             lc = 0;
  154:    *             color = 0;
  155:    *             draw = true;
  156:    *             fixed = false;
  157:    *             on = false;
  158:    *             level = 0;
  159:    *             debris = false;
  160:    *             bmp = NULL;
  161:    *             transdeb = false;
  162:    *             d = NULL;
  163:    *             r = NULL;
  164:    *             mvt = 0;
  165:    *             nullstate = false;
  166:    *             damage = NULL;
  167:    *             dmult = 1;
  168:    *             dtmult = 1;
  169:    *             draw2 = true;
  170:    *             life = -5;
  171:    *         }
  172:          };
  173:          
  174:    *     atom atoms[MAXATOMS];
  175:          int numatoms;
  176:          
  177:          atom *structure[100][100];
  178:          
  179:          struct debrisitem {
  180:              atom *me;
  181:              bool on;
  182:              int offx, offy;
  183:              int eoffx, eoffy, ew, eh;
  184:              float angle;
  185:              bool drew;
  186:              bool accrue;
  187:          
  188:    *         debrisitem() {
  189:    *             init();
  190:    *         }
  191:          
  192:    *         void init() {
  193:    *             me = NULL;
  194:    *             on = false;
  195:    *             offx = -5;
  196:    *             offy = -5;
  197:    *             eoffx = -12; eoffy = -12; ew = 24; eh = 24;
  198:    *             angle = 0;
  199:    *             drew = false;
  200:    *             accrue = true;
  201:    *         }
  202:          
  203:    *         void draw() {
  204:    *             if(me->on == false) {
  205:    *                 on = false;
  206:    *                 return;
  207:                  }
  208:    *             if(me->x - 5 > lx && me->x + 5 < rx) {
  209:    *                 if(me->bmp == NULL) return;
  210:          
  211:    *                 if(me->ix > .1 || me->iy > .1) {
  212:    *                     angle = atan2(me->iy, me->ix);
  213:    *                     angle *= convk;
  214:                      }
  215:    *                 rotate_sprite(buf, me->bmp, me->x + offx, me->y + offy, itofix(angle));
  216:    *                 drew = true;
  217:                  }
  218:    *         }
  219:          
  220:    *         void erase() {
  221:    *             if(!drew) return;
  222:    *             if(me->bmp == NULL) return;
  223:    *             blit(bg, buf, me->x + eoffx, me->y + eoffy, me->x + eoffx, me->y + eoffy, ew, eh);  
  224:    *             drew = false;
  225:    *         }
  226:          
  227:    *         void kill() {
  228:    *             erase();
  229:    *             on = false;
  230:    *         }
  231:          };
  232:          
  233:    *     debrisitem debris[MAXDEBRIS];
  234:          
  235:          struct box {
  236:              atom *list[50];
  237:              int count;
  238:          
  239:    *         box() {
  240:    *             count = 0;
  241:    *         }
  242:          };
  243:          
  244:    *     box boxes[MAXBOXX][MAXBOXY];
  245:          //10x10 boxes
  246:          
  247:          struct link {
  248:              atom *a, *b;
  249:          
  250:              float rl;
  251:              float bp;
  252:          
  253:              bool draw;
  254:              bool drew;
  255:              bool on;
  256:          
  257:              int color;
  258:          
  259:              poly *p[4];
  260:          
  261:    *         link() {
  262:    *             init();
  263:    *         }
  264:          
  265:    *         void init() {
  266:    *             draw = true;
  267:    *             on = false;
  268:    *             p[0] = p[1] = p[2] = p[3] = NULL;
  269:    *             color = 0;
  270:    *             bp = 00;
  271:    *             rl = 10;
  272:    *             a = NULL;
  273:    *             b = NULL;
  274:    *             drew = false;
  275:    *         }
  276:          };
  277:          
  278:    *     link links[MAXLINKS];
  279:          int numlinks;
  280:          
  281:          struct poly {
  282:              atom *a, *b, *c;
  283:              float *ax, *bx, *cx, *ay, *by, *cy;
  284:              link *l1, *l2, *l3;
  285:              
  286:              bool trans;
  287:              bool on;
  288:              bool drew;
  289:              int type;
  290:              
  291:              BITMAP **tmap;
  292:              BITMAP **transmap;
  293:              //BITMAP *thold;
  294:              V3D_f *v1,*v2,*v3;
  295:          
  296:    *         poly() {
  297:    *             init();
  298:    *         }
  299:          
  300:    *         void init() {
  301:    *             ax = bx = cx = 0;
  302:    *             ay = by = cy = 0;
  303:    *             trans = false;
  304:    *             on = false;
  305:    *             drew = false;
  306:    *             type = 0;
  307:    *         }
  308:          };
  309:          
  310:    *     poly polys[MAXPOLYS];
  311:          int numpolys;
  312:          
  313:          struct object {
  314:              BITMAP *obj;
  315:              BITMAP *origobj;
  316:              BITMAP *transmap;
  317:              float x, y;
  318:          
  319:    *         object() {
  320:    *             x = 0;
  321:    *             y = 0;
  322:    *             obj = NULL;
  323:    *             origobj = NULL;
  324:    *             transmap = NULL;
  325:    *         }
  326:          
  327:    *         void reset() {
  328:    *             if(origobj != NULL) destroy_bitmap(origobj);
  329:    *             if(transmap != NULL) destroy_bitmap(transmap);
  330:    *             origobj = NULL;
  331:    *             obj = NULL;
  332:    *             transmap = NULL;
  333:                  //if(transmap != NULL) destroy_bitmap(transmap);
  334:                  //transmap = NULL;
  335:    *         }
  336:          };
  337:          
  338:    *     object objects[MAXOBJECTS];
  339:          int numobjects;
  340:          
  341:          struct rigidbody {
  342:              float offset[MAXRATOMS][2];         //Maximum of 100 atoms, each with a 2 coordinate offset vector
  343:              float ouv[MAXRATOMS][2];            //Stored ***ORTHOGONAL to OFFSET*** unit vectors. Used because the projection of the force vector onto this direction will give the effective force
  344:              float ol[MAXRATOMS];                //Stored length of offets, for use in computing torque
  345:              atom *atomlist[MAXRATOMS];
  346:              int mynumatoms;
  347:              poly *polylist[MAXATOMS];
  348:              int mynumpolys;
  349:              float x, y, ix, iy, mx, my;
  350:              float ang, ia;
  351:              float rm, ram;
  352:              float gmult;    //gravity multiplier
  353:              float afric;    //angular friction
  354:              float gfric;    //ground friction (not implemented)
  355:              float grmult;   //ground multiplier
  356:              float imult;    //incline multiplier
  357:              bool on;
  358:              float turning;
  359:              float polylistx[100];
  360:              float polylisty[100];
  361:              float grounddamagethreshold;
  362:          
  363:    *         rigidbody() {
  364:    *             init();
  365:    *         }
  366:          
  367:    *         void init() {
  368:                  int a, c;
  369:    *             mynumatoms = 0;
  370:    *             mynumpolys = 0;
  371:    *             x = y = ix = iy = mx = my = ang = ia = 0;
  372:    *             rm = 0.006;
  373:    *             ram = 0.00001;
  374:    *             gmult = 180;
  375:    *             grmult = 1;
  376:    *             imult = 1;
  377:    *             grounddamagethreshold = 1.5;
  378:          
  379:    *             for(a = 0; a < MAXRATOMS; a++) {
  380:    *                 ol[a] = 0;
  381:    *                 for(c = 0; c < 2; c++) {
  382:    *                     offset[a][c] = 0;
  383:    *                     ouv[a][c] = 0;
  384:    *                 }
  385:    *             }
  386:    *             on = false;
  387:    *             afric = 0.95;
  388:    *             gfric = 0.001;
  389:    *             turning = 1;
  390:    *         }
  391:          
  392:    *         void addatom(atom *a) {
  393:    *             atomlist[mynumatoms] = a;
  394:    *             mynumatoms++;
  395:    *         }
  396:          
  397:    *         void addpoly(poly *p) {
  398:    *             polylist[mynumpolys] = p;
  399:    *             mynumpolys++;
  400:    *         }
  401:          
  402:    *         void complete() {
  403:                  float nx, ny;
  404:                  float tx, ty;
  405:                  int i;
  406:                  float dx, dy, dist, m, om, ox, oy, od;
  407:                  atom *a;
  408:                  
  409:    *             tx = ty = 0;
  410:          
  411:    *             for(i = 0; i < mynumatoms; i++) {
  412:    *                 tx += atomlist[i]->x;
  413:    *                 ty += atomlist[i]->y;
  414:    *             }
  415:    *             nx = tx / (mynumatoms);
  416:    *             ny = ty / (mynumatoms);
  417:    *             x = nx;
  418:    *             y = ny;
  419:                  //x = 530;
  420:                  //y = 370;
  421:          
  422:    *             for(i = 0; i < mynumatoms; i++) {
  423:    *                 a = atomlist[i];
  424:          
  425:    *                 dx = a->x - x;
  426:    *                 dy = a->y - y;
  427:    *                 offset[i][0] = dx;
  428:    *                 offset[i][1] = dy;
  429:    *                 dist = sqrt(dx * dx + dy * dy);
  430:    *                 ol[i] = dist;
  431:    *                 m = dy / dx;
  432:    *                 if(m != 0) {
  433:    *                     om = (-1) / m;
  434:    *                     ox = 1;
  435:    *                     oy = om;
  436:                      }
  437:    *                 else {
  438:    .                     om = 0;
  439:    .                     ox = 0;
  440:    .                     oy = 1;
  441:                      }
  442:    *                 od = sqrt(1 + oy * oy);
  443:    *                 ox = ox / od;
  444:    *                 oy = oy / od;
  445:    *                 if(dy > 0) {
  446:    *                     ox = -ox;
  447:    *                     oy = -oy;
  448:                      }
  449:    *                 ouv[i][0] = ox;
  450:    *                 ouv[i][1] = oy;
  451:    *                 a->r = this;
  452:    *             }
  453:    *             on = true;
  454:    *         }
  455:          
  456:    *         void update() {
  457:    *             if(!on) return;
  458:                  int i;
  459:                  //atom **ap;
  460:                  //float (*o)[2];
  461:                  atom *a;
  462:                  
  463:                  int j;
  464:                  int nbx, nby;
  465:                  int gy;
  466:                  float ca, sa;
  467:                  float x1, y1;
  468:                  float f, d;
  469:                  int gx;
  470:                  float dist, dx, dy;
  471:                  float force, fx, fy;
  472:                  box *b;
  473:    *             const float FK1 = 4;
  474:    *             const float FK2 = 50;
  475:    *             const float FK3 = 1;
  476:          
  477:    *             ca = cos(ang);
  478:    *             sa = sin(ang);
  479:          
  480:    *             for(i = 0; i < mynumatoms; i++) {
  481:    *                 a = atomlist[i];
  482:    *                 d = ol[i];
  483:          
  484:    *                 ix += a->ix;
  485:    *                 iy += a->iy;
  486:    *                 mx += a->mx;
  487:    *                 my += a->my;
  488:          
  489:    *                 x1 = ouv[i][0];
  490:    *                 y1 = ouv[i][1];
  491:    *                 f = (a->ix * (x1 * ca - y1 * sa) + a->iy * (x1 * sa + y1 * ca)) * d;
  492:    *                 ia += f;
  493:          
  494:    *                 a->ix = 0;
  495:    *                 a->iy = 0;
  496:    *                 a->mx = 0;
  497:    *                 a->my = 0;
  498:    *             }
  499:                      
  500:                  //if(fabs(ix) < .1) ix = 0;
  501:                  //if(fabs(my) < .1) mx = 0;
  502:                  //if(fabs(iy) < .2) iy = 0;
  503:                  //if(fabs(my) < .2) my = 0;
  504:          
  505:    *             x += (ix + mx) * rm;
  506:    *             y += (iy + my) * rm;
  507:    *             mx = 0;
  508:    *             my = 0;
  509:    *             ix *= FLUIDFRICTION;
  510:    *             iy *= FLUIDFRICTION;
  511:                  //ia *= 0.95;//FLUIDFRICTION;
  512:    *             ia *= afric;
  513:    *             if(afric == 0.95) {
  514:    .                 if(ia * ram > .02) ia = 0.02 / ram;
  515:    .                 if(ia * ram < -.02) ia = -0.02 / ram;
  516:    .                 if(fabs(ia * ram) < 0.002) ia = 0;
  517:                  }
  518:    *             ang += ia * ram;
  519:                  //ang = 0;
  520:          
  521:    *             ca = cos(ang);
  522:    *             sa = sin(ang);
  523:                  
  524:    *             if(y < waterlevel) {
  525:    *                 iy += gmult * GRAVITY;
  526:                  }
  527:    *             else {
  528:    .                 iy -= gmult * GRAVITY;
  529:                      //iy *= 0.99;
  530:                      //ix *= 0.999;
  531:                  }
  532:          
  533:    *             for(i = 0; i < mynumatoms; i++) {
  534:    *                 a = atomlist[i];
  535:          
  536:    *                 x1 = offset[i][0];
  537:    *                 y1 = offset[i][1];
  538:    *                 a->x = x + (x1*ca - y1*sa);
  539:    *                 a->y = y + (x1*sa + y1*ca);
  540:          
  541:    *                 if(mynumpolys != 0) {
  542:    *                     x1 = offset[i][0] * turning;
  543:    *                     y1 = offset[i][1];
  544:    *                     polylistx[i] = x + (x1*ca - y1*sa);
  545:    *                     polylisty[i] = y + (x1*sa + y1*ca);
  546:                      }
  547:          
  548:                      /*
  549:                      gfric = 0.997;
  550:          
  551:                      if(a->y > path[(int)a->x] + 0) {
  552:                          ix *= gfric;
  553:                          circlefill(buf, a->x, a->y, 5, magenta);
  554:                      }
  555:                      */
  556:          
  557:    *                 if(a->y > path[(int)a->x]) {
  558:          
  559:    *                     gx = (int)(a->x + 4);
  560:    *                     gy = path[gx] + 23;
  561:                          
  562:    *                     dx = (a->x - gx);
  563:    *                     dy = (a->y - gy);
  564:          
  565:    *                     if(dx < 20 && dy < 20 && dx > -20 && dy > -20) {
  566:    *                         dist = (float)(sqrt(dx * dx + dy * dy));
  567:    *                         if(dist < 20 && dist != 0) {
  568:    *                             force = (20 - dist) * REPULSESTRENGTH * grmult;
  569:    *                             fx = (dx / dist) * force;
  570:    *                             fy = (dy / dist) * force;
  571:    *                             a->ix += FK1*fx;
  572:    *                             a->iy += FK3*fy;
  573:    *                             a->mx += FK2*fx *imult;
  574:    *                             a->my += FK3*fy;
  575:    *                             if(force > grounddamagethreshold && a->damage != NULL) {
  576:    .                                 *(a->damage) += force * 10;
  577:                                  }
  578:    *                             a->ix += -ix * gfric;
  579:                                  //a->ix *= 0;//gfric;
  580:                              }
  581:                          }
  582:          
  583:    *                     gx = (int)(a->x - 3);
  584:    *                     gy = path[gx] + 23;
  585:                          
  586:    *                     dx = (a->x - gx);
  587:    *                     dy = (a->y - gy);
  588:          
  589:    *                     if(dx < 20 && dy < 20 && dx > -20 && dy > -20) {
  590:    *                         dist = (float)(sqrt(dx * dx + dy * dy));
  591:    *                         if(dist < 20 && dist != 0) {
  592:    *                             force = (20 - dist) * REPULSESTRENGTH * grmult;
  593:    *                             fx = (dx / dist) * force;
  594:    *                             fy = (dy / dist) * force;
  595:    *                             a->ix += FK1*fx;
  596:    *                             a->iy += FK3*fy;
  597:    *                             a->mx += FK2*fx *imult;
  598:    *                             a->my += FK3*fy;
  599:    *                             if(force > grounddamagethreshold && a->damage != NULL) {
  600:    .                                 *(a->damage) += force * 10;
  601:                                  }
  602:    *                             a->ix += -ix * gfric;
  603:                                  //a->ix *= 0;//gfric;
  604:                              }
  605:                          }
  606:          
  607:    *                     if(a->x < 0) {
  608:    .                         x++;
  609:    .                         ix = -ix * 0.5;
  610:    .                         gy = 800;
  611:                          }
  612:    *                     if(a->x > buf->w - 2) {
  613:    .                         x -= 2;
  614:    .                         ix = -ix * 0.5;
  615:                          }       
  616:    *                     if(a->y < 0) {
  617:    .                         y++;
  618:    .                         iy = -iy * 0.5;
  619:                          }
  620:    *                     if(a->y > buf->h - 1) {
  621:    .                         y--;
  622:    .                         iy = -iy * 0.5;
  623:                          }
  624:          
  625:                          /*
  626:                          gy = path[(int)(a->x)];
  627:                          if(a->x - 5 > 0 && a->x - 5 < buf->w - 1) {
  628:                              gl = path[(int)(a->x - 5)];
  629:                          }
  630:                          else gl = 0;
  631:                          if(a->x + 5 > 0 && a->x + 5 < buf->w - 1) {
  632:                              gr = path[(int)(a->x + 5)];
  633:                          }
  634:                          else gl = 0;
  635:                          */
  636:                      }
  637:          
  638:    *                 nbx = ((int)(a->x) / 10) + 2;
  639:    *                 nby = ((int)(a->y) / 10) + 2;
  640:          
  641:    *                 if(nbx != a->bx || nby != a->by) {
  642:    *                     b = &(boxes[a->bx][a->by]);
  643:    *                     j = 0;
  644:    *                     b->count--;
  645:    *                     while(j < b->count && b->list[j] != a) j++;
  646:    *                     b->list[j] = b->list[b->count];
  647:          
  648:    *                     b = &(boxes[nbx][nby]);
  649:    *                     if(b->count < 45) {
  650:    *                         b->list[b->count] = a;
  651:    *                         b->count++;
  652:                          }
  653:    *                     a->bx = nbx;
  654:    *                     a->by = nby;
  655:                      }
  656:    *             }
  657:    *         }
  658:          };
  659:          
  660:    *     rigidbody rigidbodies[MAXRIGIDBODIES];
  661:          int numrigidbodies;
  662:          
  663:    *     rigidbody *addrigidbody(float rm, float ram, float gmult) {
  664:              rigidbody *r;
  665:    *         r = &(rigidbodies[numrigidbodies]);
  666:    *         r->rm = rm;
  667:    *         r->ram = ram;
  668:    *         r->gmult = gmult;
  669:    *         numrigidbodies++;
  670:          
  671:    *         return r;
  672:    *     }
  673:          
  674:    *     void destroyvehiclerigidbody(rigidbody *r) {
  675:              int i;
  676:              float mult;
  677:              atom *a;
  678:              poly *p;
  679:    *         mult = 1 / (r->gmult * 0.125);
  680:    *         for(i = 0; i < r->mynumatoms; i++) {
  681:    *             a = r->atomlist[i];
  682:    *             a->r = NULL;    
  683:    *             a->rmdt = 0.5;
  684:    *             a->ix = r->ix * mult;
  685:    *             a->iy = r->iy * mult;
  686:    *         }
  687:    *         for(i = 0; i < r->mynumpolys; i++) {
  688:    *             p = r->polylist[i];
  689:    *             p->ax = &(p->a->x);
  690:    *             p->ay = &(p->a->y);
  691:    *             p->bx = &(p->b->x);
  692:    *             p->by = &(p->b->y);
  693:    *             p->cx = &(p->c->x);
  694:    *             p->cy = &(p->c->y);
  695:    *         }
  696:    *         r->on = false;
  697:    *     }
  698:          
  699:    .     void destroyrigidbody(rigidbody *r) {
  700:              int i;
  701:              atom *a;
  702:    .         for(i = 0; i < r->mynumatoms; i++) {
  703:    .             a = r->atomlist[i];
  704:    .             a->r = NULL;
  705:    .         }
  706:    .         r->on = false;
  707:    .     }
  708:          
  709:    *     void updaterigidbodies() {
  710:              rigidbody *r;
  711:              int i;
  712:    *         r = &(rigidbodies[0]);
  713:    *         for(i = 0; i < numrigidbodies; i++) {
  714:    *             r->update();
  715:    *             r++;
  716:    *         }
  717:    *     }
  718:          
  719:    *     atom *addatom(float x, float y, bool levels[MAXLEVELS], int level) {
  720:              atom *a;
  721:              box *b;
  722:              int nbx, nby, i;
  723:              link **l;
  724:          
  725:    *         a = &(atoms[0]);
  726:    *         while(a->on) a++;
  727:          
  728:              //a->init();
  729:              
  730:    *         l = &(a->l[0]);
  731:    *         for(i = 0; i < 8; i++) {
  732:    *             *l = NULL;
  733:    *             l++;
  734:    *         }
  735:          
  736:    *         for(i = 0; i < MAXLEVELS; i++) {
  737:    *             a->levels[i] = levels[i];
  738:    *         }
  739:          
  740:    *         a->level = level;
  741:          
  742:    *         a->x = x;
  743:    *         a->y = y;
  744:    *         a->dmult = 1;
  745:    *         a->life = -5;
  746:          
  747:    *         a->debris = false;
  748:    *         nbx = (int)a->x / 10 + 2;
  749:    *         nby = (int)a->y / 10 + 2;
  750:    *         b = &(boxes[nbx][nby]);
  751:    *         b->list[b->count] = a;
  752:    *         b->count++;
  753:    *         a->bx = nbx;
  754:    *         a->by = nby;
  755:    *         a->rmdt = DELTAT;
  756:    *         a->fixed = false;
  757:    *         a->color = gray;
  758:    *         a->draw = true;
  759:    *         a->draw2 = true;
  760:    *         a->on = true;
  761:    *         a->dmult = 1;
  762:    *         a->dtmult = 1;
  763:              
  764:    *         if(a == &(atoms[numatoms])) {
  765:    *             numatoms++;
  766:              }
  767:          
  768:    *         return a;
  769:    *     }
  770:          
  771:    *     void addlink(atom *a, atom *b, float rl, float bp) {
  772:              link *l, **p;
  773:          
  774:    *         l = &(links[0]);
  775:    *         while(l->on) l++;
  776:          
  777:    *         l->init();
  778:    *         l->a = a;
  779:    *         l->b = b;
  780:    *         l->rl = rl;
  781:    *         l->bp = bp;
  782:    *         l->on = true;
  783:    *         l->color = gray;
  784:          
  785:    *         p = &(a->l[0]);
  786:    *         while(*p != NULL) p++;
  787:    *         *p = l;
  788:    *         a->lc++;
  789:          
  790:    *         p = &(b->l[0]);
  791:    *         while(*p != NULL) p++;
  792:    *         *p = l;
  793:    *         b->lc++;
  794:          
  795:    *         if(a->draw == false && b->draw == false || 1) 
  796:    *             l->draw = false;
  797:    *         else
  798:    .             l->draw = true;
  799:          
  800:    *         if(l == &(links[numlinks])) {
  801:    *             numlinks++;
  802:              }
  803:    *     }
  804:          
  805:    *     bool overlap(atom *a, atom *b, atom *c, atom *x, atom *y) {
  806:    *         if(x == a && y == b) return true;
  807:    *         if(x == b && y == c) return true;
  808:    *         if(x == c && y == a) return true;
  809:    *         if(x == b && y == a) return true;
  810:    *         if(x == c && y == b) return true;
  811:    *         if(x == a && y == c) return true;
  812:    *         return false;
  813:    *     }
  814:          
  815:    *     poly *addpoly(atom *a, atom *b, atom *c) {
  816:              poly *p;
  817:              link *l;
  818:              int i, j, k;
  819:          
  820:    *         p = &(polys[0]);
  821:    *         while(p->on) p++;
  822:          
  823:    *         p->init();
  824:          
  825:    *         p->a = a;
  826:    *         p->b = b;
  827:    *         p->c = c;
  828:    *         p->ax = &(a->x);
  829:    *         p->ay = &(a->y);
  830:    *         p->bx = &(b->x);
  831:    *         p->by = &(b->y);
  832:    *         p->cx = &(c->x);
  833:    *         p->cy = &(c->y);
  834:    *         p->on = true;
  835:          
  836:    *         k = 0;
  837:    *         l = &(links[0]);
  838:    *         for(i = 0; i < numlinks; i++) {
  839:    *             if(overlap(a, b, c, l->a, l->b)) {
  840:    *                 for(j = 0; j < 4; j++) {
  841:    *                     if(l->p[j] == NULL) {
  842:    *                         l->p[j] = p;
  843:    *                         if(k == 0)
  844:    *                             p->l1 = l;
  845:    *                         else if(k == 1)
  846:    *                             p->l2 = l;
  847:    *                         else if(k == 2)
  848:    *                             p->l3 = l;
  849:    *                         k++;
  850:    *                         j = 5;
  851:                          }
  852:    *                 }
  853:                  }
  854:    *             l++;
  855:    *         }
  856:          
  857:    *         if(p == &(polys[numpolys])) {
  858:    *             numpolys++;
  859:              }
  860:    *         return p;
  861:    *     }
  862:          
  863:    .     void do_repulseforceold(atom *a1, atom *a2) {
  864:              int dx, dy;
  865:              float fx, fy;
  866:    .         dx = (int)(a1->x - a2->x) + 10;
  867:    .         dy = (int)(a1->y - a2->y) + 10;
  868:    .         if(dx >= 20 || dy >= 20 || dx < 0 || dy < 0) return;
  869:          
  870:    .         fx = forcetable_repulse_x[dx][dy];
  871:    .         fy = forcetable_repulse_y[dx][dy];
  872:          
  873:    .         a1->ix += fx;
  874:    .         a1->iy += fy;
  875:    .         a2->ix -= fx;
  876:    .         a2->iy -= fy;
  877:    .     }           
  878:          
  879:    *     void do_repulseforce(atom *a1, atom *a2) {
  880:              link **l;
  881:              int i;
  882:    *         if(a1->nullstate && a2->nullstate) return;  
  883:              /*
  884:              if(a1 == NULL || a2 == NULL) 
  885:                  fprintf(debug, "a1 = %i, a2 = %i\n", a1, a2);
  886:              if(a1 == NULL || a2 == NULL)
  887:                  return;
  888:              */
  889:    *         if(a1->on == false || a2->on == false) return;
  890:    *         if(a1->levels[a2->level] == false) return;
  891:              
  892:    *         l = &(a1->l[0]);
  893:    *         for(i = 0; i < 8; i++) {
  894:    *             if((*l) != NULL && ((*l)->a == a2 || (*l)->b == a2)) return;
  895:    *             l++;
  896:    *         }
  897:          
  898:              float dist, dx, dy;
  899:              float force, fx, fy;
  900:    *         dx = (int)(a1->x - a2->x);
  901:    *         dy = (int)(a1->y - a2->y);
  902:          
  903:    *         if(dx < 10 && dy < 10 && dx > -10 && dy > -10) {
  904:    *             dist = (float)(sqrt(dx * dx + dy * dy));
  905:    *             if(dist == 0) {
  906:    *                 dist = dx = dy = 0.1;
  907:                  }
  908:    *             if(dist < 10) {
  909:    *                 force = (10 - dist) * REPULSESTRENGTH;
  910:    *                 fx = (dx / dist) * force;
  911:    *                 a1->ix += fx;
  912:    *                 a2->ix -= fx;
  913:          
  914:    *                 fy = (dy / dist) * force;
  915:    *                 a1->iy += fy;
  916:    *                 a2->iy -= fy;
  917:          
  918:    *                 a1->mx += fx;// / 1;
  919:    *                 a2->mx -= fx;// / 1;
  920:    *                 a1->my += fy;// / 1;
  921:    *                 a2->my -= fy;// / 1;
  922:                      
  923:    *                 if(a1->damage != NULL) {
  924:    *                     if(force > 0.5) {
  925:    *                         *(a1->damage) += 3 * (force - 0.5) * a2->dmult * a1->dtmult;
  926:                          }
  927:                      }
  928:    *                 if(a2->damage != NULL) {
  929:    *                     if(force > 0.5) {
  930:    *                         *(a2->damage) += 3 * (force - 0.5) * a1->dmult * a2->dtmult;
  931:                          }
  932:                      }
  933:                  }
  934:              }
  935:    *     }
  936:          
  937:    *     void destroyatom(atom *a) {
  938:              box *b;
  939:              int i;
  940:          
  941:    *         a->on = false;
  942:    *         a->draw = false;
  943:    *         a->draw2 = false;
  944:          
  945:    *         if(a->bmp != NULL) {
  946:    *             destroy_bitmap(a->bmp);
  947:    *             a->bmp = NULL;
  948:              }
  949:          
  950:    *         b = &(boxes[a->bx][a->by]);
  951:    *         i = 0;
  952:    *         while(i < b->count && b->list[i] != a) i++;
  953:    *         if(b->list[i] == a) {
  954:    *             b->count--;
  955:    *             b->list[i] = b->list[b->count];
  956:              }
  957:    *         a->init();
  958:    *     }
  959:          
  960:    .     int findlow(float a, float b) {
  961:    .         if(a < b) return (int)a;
  962:    .         return (int)b;
  963:    .     }
  964:          
  965:    .     int findhigh(float a, float b) {
  966:    .         if(a > b) return (int)a;
  967:    .         return (int)b;
  968:    .     }
  969:          
  970:    *     int findlow(float a, float b, float c) {
  971:    *         if(a <= b && a <= c) return (int)a;
  972:    *         if(b <= a && b <= c) return (int)b;
  973:    *         if(c <= b && c <= a) return (int)c;
  974:    .         return 0;
  975:    *     }
  976:          
  977:    *     int findhigh(float a, float b, float c) {
  978:    *         if(a >= b && a >= c) return (int)a + 1;
  979:    *         if(b >= a && b >= c) return (int)b + 1;
  980:    *         if(c >= b && c >= a) return (int)c + 1;
  981:    .         return 0;
  982:    *     }
  983:          
  984:          /*
  985:          void alphablit(BITMAP *source, BITMAP *dest, int x1, int y1, int x2, int y2, int w, int h) {
  986:              int x, y;
  987:          
  988:              for(x = 0; x < w; x++) {
  989:                  for(y = 0; y < h; y++) {
  990:                      if(getpixel(dest, x + x2, y + y2) != magenta) {
  991:                          putpixel(dest, x + x2, y + y2, getpixel(source, x + x1, y + y1)
  992:          */
  993:          
  994:    .     void crazyoverlay(BITMAP *dest, BITMAP *source, int sx, int sy) {
  995:              int x, y, c;
  996:    .         for(x = sx; x < sx + source->w; x++) {
  997:    .             for(y = sy; y < sy + source->h; y++) {
  998:                      //if(x >= 0 && x < dest->w && y >= 0 && y < dest->h) {
  999:    .                     c = getpixel(source, x - sx, y - sy);
 1000:    .                     if(getr32(c) == 255 && getg32(c) == 0 && getb32(c) == 255)//magenta)
 1001:    .                         putpixel(dest, x, y, c);
 1002:                      //}
 1003:    .             }
 1004:    .         }
 1005:    .     }
 1006:          
 1007:    *     void destroypoly(poly *p) {
 1008:              int i, x, y;
 1009:          
 1010:              //p->a->draw = true;
 1011:              //p->b->draw = true;
 1012:              //p->c->draw = true;
 1013:          
 1014:    *         p->on = false;
 1015:          
 1016:    *         if(p->transmap != NULL) {
 1017:    .             x = findlow(p->v1->u, p->v2->u, p->v3->u) + 5 - 20;
 1018:    .             y = findlow(p->v1->v, p->v2->v, p->v3->v) + 5 - 20;
 1019:    .             draw_trans_sprite(*(p->tmap), debrisr[p->type], x, y);
 1020:                  //draw_trans_sprite(*(p->transmap), debrisrm[p->type], x, y);
 1021:    .             crazyoverlay(*(p->transmap), debrisrm[p->type], x, y);
 1022:          
 1023:                  BITMAP *tmp;
 1024:    .             tmp = create_bitmap_ex(32, 40, 40);
 1025:    .             blit(*(p->transmap), tmp, x, y, 0, 0, 40, 40);
 1026:    .             draw_trans_sprite(*(p->tmap), tmp, x, y);
 1027:                  //draw_trans_sprite(buf, *(p->transmap), 100, 100);
 1028:              }
 1029:          
 1030:              /*
 1031:              fprintf(debug, "free!");
 1032:              p->l1->draw = true;
 1033:              //p->l1->a->draw = true;
 1034:              //p->l1->b->draw = true;
 1035:          
 1036:              p->l2->draw = true;
 1037:              //p->l2->a->draw = true;
 1038:              //p->l2->b->draw = true;
 1039:          
 1040:              p->l3->draw = true;
 1041:              //p->l3->a->draw = true;
 1042:              //p->l3->b->draw = true;
 1043:              fprintf(debug, "alive!");
 1044:              */
 1045:          
 1046:              /*
 1047:              if(p->l1->p[0] != NULL) p->l1->p[0]->trans = true;
 1048:              if(p->l1->p[1] != NULL) p->l1->p[1]->trans = true;
 1049:              if(p->l1->p[2] != NULL) p->l1->p[2]->trans = true;
 1050:              if(p->l1->p[3] != NULL) p->l1->p[3]->trans = true;
 1051:          
 1052:              if(p->l2->p[0] != NULL) p->l2->p[0]->trans = true;
 1053:              if(p->l2->p[1] != NULL) p->l2->p[1]->trans = true;
 1054:              if(p->l2->p[2] != NULL) p->l2->p[2]->trans = true;
 1055:              if(p->l2->p[3] != NULL) p->l2->p[3]->trans = true;
 1056:          
 1057:              if(p->l3->p[0] != NULL) p->l3->p[0]->trans = true;
 1058:              if(p->l3->p[1] != NULL) p->l3->p[1]->trans = true;
 1059:              if(p->l3->p[2] != NULL) p->l3->p[2]->trans = true;
 1060:              if(p->l3->p[3] != NULL) p->l3->p[3]->trans = true;
 1061:              */
 1062:          
 1063:    *         p->type = 0;
 1064:          
 1065:    *         for(i = 0; i < 4; i++) {
 1066:    *             if(p->l1->p[i] == p) {
 1067:    *                 p->l1->p[i] = NULL;
 1068:                  }
 1069:    *         }
 1070:          
 1071:              ///*
 1072:    *         for(i = 0; i < 4; i++) {
 1073:    *             if(p->l1->p[i] != NULL) {
 1074:    *                 i = 10;
 1075:    *                 break;
 1076:                  }
 1077:    *         }
 1078:    *         if(i != 10) {
 1079:    *             p->l1->draw = true;
 1080:                  //p->l1->a->draw = true;
 1081:                  //p->l1->b->draw = true;
 1082:              }
 1083:              //*/
 1084:          
 1085:    *         for(i = 0; i < 4; i++) {
 1086:    *             if(p->l2->p[i] == p) {
 1087:    *                 p->l2->p[i] = NULL;
 1088:                  }
 1089:    *         }
 1090:          
 1091:              ///*
 1092:    *         for(i = 0; i < 4; i++) {
 1093:    *             if(p->l2->p[i] != NULL) {
 1094:    *                 i = 10;
 1095:    *                 break;
 1096:                  }
 1097:    *         }
 1098:    *         if(i != 10) {
 1099:    *             p->l2->draw = true;
 1100:                  //p->l2->a->draw = true;
 1101:                  //p->l2->b->draw = true;
 1102:              }
 1103:              //*/
 1104:          
 1105:    *         for(i = 0; i < 4; i++) {
 1106:    *             if(p->l3->p[i] == p) {
 1107:    *                 p->l3->p[i] = NULL;
 1108:                  }
 1109:    *         }
 1110:          
 1111:              ///*
 1112:    *         for(i = 0; i < 4; i++) {
 1113:    *             if(p->l3->p[i] != NULL) {
 1114:    *                 i = 10;
 1115:    *                 break;
 1116:                  }
 1117:    *         }
 1118:    *         if(i != 10) {
 1119:    *             p->l3->draw = true;
 1120:                  //p->l3->a->draw = true;
 1121:                  //p->l3->b->draw = true;
 1122:              }
 1123:              //*/
 1124:    *     }
 1125:              
 1126:    *     void do_linkforce(link *l) {
 1127:    *         if(l->a->nullstate && l->b->nullstate) return;
 1128:              int i;
 1129:              float dist, dx, dy;
 1130:              float force, fx, fy;
 1131:    *         dx = (l->a->x - l->b->x);
 1132:    *         dy = (l->a->y - l->b->y);
 1133:    *         bool broke = false;
 1134:              link **lp;
 1135:              bool tmp;
 1136:              
 1137:    *         if(dx < l->bp && dy < l->bp && dx > -l->bp && dy > -l->bp) {
 1138:    *             dist = (float)(sqrt(dx * dx + dy * dy));
 1139:    *             if(dist == 0) {
 1140:    .                 dist = dx = dy = 0;
 1141:    .                 return;
 1142:                  }
 1143:    *             if(dist < l->bp) {
 1144:    *                 force = (l->rl - dist) * LINKSTRENGTH;
 1145:    *                 fx = (dx / dist) * force;
 1146:          
 1147:    *                 l->a->ix += fx;
 1148:    *                 l->b->ix -= fx;
 1149:          
 1150:    *                 fy = (dy / dist) * force;
 1151:    *                 l->a->iy += fy;
 1152:    *                 l->b->iy -= fy;
 1153:          
 1154:    *                 l->a->mx += fx * .3;
 1155:    *                 l->b->mx -= fx * .3;
 1156:    *                 l->a->my += fy * .3;
 1157:    *                 l->b->my -= fy * .3;
 1158:                  }
 1159:    *             else
 1160:    *                 broke = true;
 1161:              }
 1162:    *         else
 1163:    *             broke = true;
 1164:          
 1165:    *         if(l->a->r != NULL || l->b->r != NULL) broke = false;
 1166:          
 1167:    *         if(broke) {
 1168:    *             dopanvol(l->a->x, 0.2);
 1169:    *             if(expc % 5 == 0) play_sample(explodesmall, vol * 0.7, pan, 1000, 0);
 1170:    *             expc++;
 1171:    *             l->on = false;
 1172:          
 1173:                  int count;
 1174:          
 1175:    *             count = 0;
 1176:    *             for(i = 0; i < 8; i++) {
 1177:    *                 if(l->a->l[i] != NULL) {
 1178:    *                     count++;
 1179:                      }
 1180:    *             }
 1181:          
 1182:    *             for(i = 0; i < 8; i++) {
 1183:    *                 if(l->a->l[i] != NULL) {
 1184:    *                     if(count <= 3) {
 1185:    *                         l->a->l[i]->bp = 0;
 1186:                          }
 1187:                          //l->a->l[i]->bp -= 0.1;
 1188:    *                     if(l->a->l[i] == l) {
 1189:    *                         l->a->l[i] = NULL;
 1190:                              //break;
 1191:                          }
 1192:                      }
 1193:    *             }
 1194:    *             count = 0;
 1195:    *             for(i = 0; i < 8; i++) {
 1196:    *                 if(l->b->l[i] != NULL) {
 1197:    *                     count++;
 1198:                      }
 1199:    *             }
 1200:          
 1201:    *             for(i = 0; i < 8; i++) {
 1202:    *                 if(l->b->l[i] != NULL) {
 1203:    *                     if(count <= 3) {
 1204:    *                         l->b->l[i]->bp = 0;
 1205:                          }
 1206:                          //l->a->l[i]->bp -= 0.1;
 1207:    *                     if(l->b->l[i] == l) {
 1208:    *                         l->b->l[i] = NULL;
 1209:                              //break;
 1210:                          }
 1211:                      }
 1212:    *             }
 1213:          
 1214:                  /*
 1215:                  for(i = 0; i < 8; i++) {
 1216:                      if(l->a->l[i] != NULL) {
 1217:                          l->a->l[i]->bp -= 0.1;
 1218:                          if(l->a->l[i] == l) {
 1219:                              l->a->l[i] = NULL;
 1220:                              //break;
 1221:                          }
 1222:                      }
 1223:                  }
 1224:          
 1225:                  for(i = 0; i < 8; i++) {
 1226:                      if(l->b->l[i] != NULL) {
 1227:                          l->b->l[i]->bp -= 0.1;
 1228:                          if(l->b->l[i] == l) {
 1229:                              l->b->l[i] = NULL;
 1230:                              //break;
 1231:                          }
 1232:                      }
 1233:                  }
 1234:                  */
 1235:          
 1236:    *             for(i = 0; i < 4; i++) {
 1237:    *                 if(l->p[i] != NULL) {
 1238:    *                     destroypoly(l->p[i]);
 1239:                      }
 1240:    *             }
 1241:          
 1242:                  /*
 1243:                  for(i = 0; i < 12; i++) {
 1244:                      if(l->a->p[i] != NULL) {
 1245:                          for(j = 0; j < 12; j++) {
 1246:                              if(l->a->p[i] == l->b->p[j]) {
 1247:                                  destroypoly(l->a->p[i]);
 1248:                                  break;
 1249:                              }
 1250:                          }
 1251:                      }
 1252:                  }
 1253:                  */
 1254:                  
 1255:    *             if(!l->a->fixed) {
 1256:    *                 tmp = true;
 1257:    *                 lp = &(l->a->l[0]);
 1258:    *                 for(i = 0; i < 8; i++) {
 1259:    *                     if((*lp) != NULL) {
 1260:    *                         tmp = false;
 1261:    *                         break;
 1262:                          }
 1263:    *                     lp++;
 1264:    *                 }
 1265:    *                 if(tmp) {
 1266:    *                     adddebris(l->a, true);
 1267:    *                     if(rand() % 6 == 0 && l->a->draw2)
 1268:    *                         addtrailanim(l->a, explosionsmallanim, 24, 10, rand() % 10, 500 + rand() % 1000, -2, 1, false, 1);
 1269:                      }
 1270:                  }
 1271:          
 1272:    *             if(!l->b->fixed) {
 1273:    *                 tmp = true;
 1274:    *                 lp = &(l->b->l[0]);
 1275:    *                 for(i = 0; i < 8; i++) {
 1276:    *                     if((*lp) != NULL) {
 1277:    *                         tmp = false;
 1278:    *                         break;
 1279:                          }
 1280:    *                     lp++;
 1281:    *                 }
 1282:    *                 if(tmp) {
 1283:    *                     adddebris(l->b, true);
 1284:    *                     if(rand() % 6 == 0 && l->b->draw2)
 1285:    *                         addtrailanim(l->b, explosionsmallanim, 24, 10, rand() % 10, 500 + rand() % 1000, -2, 1, false, 1);
 1286:                      }
 1287:                  }
 1288:          
 1289:    *             l->a = NULL;
 1290:    *             l->b = NULL;
 1291:              }
 1292:    *     }
 1293:                  
 1294:    *     void physics_update() {
 1295:              atom *a;
 1296:              link *l;
 1297:              box *b;
 1298:              int i, j;
 1299:              int nbx, nby;
 1300:              int gy, gl, gr;
 1301:              int dy, dl, dr;
 1302:              bool debris;
 1303:              float dmg;
 1304:              float dif;
 1305:          
 1306:    *         a = &(atoms[0]);
 1307:    *         for(i = 0; i < numatoms; i++) {
 1308:    *             if(a->life == 0) {
 1309:    *                 a->on = false;
 1310:    *                 destroyatom(a);
 1311:                  }
 1312:    *             if(a->life > 0) a->life--;
 1313:    *             if(a->on) {
 1314:    *                 a->oix = a->ix;
 1315:    *                 a->oiy = a->iy;// + GRAVITY;
 1316:    *                 a->ox = a->x;
 1317:    *                 a->oy = a->y;
 1318:                      //fprintf(debug, "1");
 1319:                      //1 - down left
 1320:    *                 b = &(boxes[a->bx - 1][a->by + 1]);
 1321:    *                 if(b->count != 0) {
 1322:    *                     for(j = 0; j < b->count; j++)  {
 1323:    *                         do_repulseforce(a, b->list[j]);
 1324:    *                     }
 1325:                      }
 1326:                      //fprintf(debug, "2");
 1327:                      //2 - down
 1328:    *                 b = &(boxes[a->bx][a->by + 1]);
 1329:    *                 if(b->count != 0) {
 1330:    *                     for(j = 0; j < b->count; j++) {
 1331:    *                         do_repulseforce(a, b->list[j]);
 1332:    *                     }
 1333:                      }
 1334:                      //fprintf(debug, "3");
 1335:                      //3 - down right
 1336:    *                 b = &(boxes[a->bx + 1][a->by + 1]);
 1337:    *                 if(b->count != 0) {
 1338:    *                     for(j = 0; j < b->count; j++) {
 1339:    *                         do_repulseforce(a, b->list[j]);
 1340:    *                     }
 1341:                      }
 1342:                      //fprintf(debug, "4");
 1343:                      //4 - right
 1344:    *                 b = &(boxes[a->bx + 1][a->by]);
 1345:    *                 if(b->count != 0) {
 1346:    *                     for(j = 0; j < b->count; j++) {
 1347:    *                         do_repulseforce(a, b->list[j]);
 1348:    *                     }
 1349:                      }
 1350:                      //fprintf(debug, "5");
 1351:                      //5 - center (special case)
 1352:    *                 b = &(boxes[a->bx][a->by]);
 1353:    *                 if(b->count != 1) {
 1354:    *                     for(j = 0; j < b->count; j++) {
 1355:    *                         if(b->list[j] < a) {
 1356:    *                             do_repulseforce(a, b->list[j]);
 1357:                              }
 1358:    *                     }
 1359:                      }
 1360:                  }
 1361:                  
 1362:    *             a++;
 1363:    *         }
 1364:          
 1365:    *         l = &(links[0]);
 1366:    *         for(i = 0; i < numlinks; i++) {
 1367:    *             if(l->on)
 1368:    *                 do_linkforce(l);
 1369:    *             l++;
 1370:    *         }
 1371:          
 1372:    *         a = &(atoms[0]);
 1373:    *         for(i = 0; i < numatoms; i++) {
 1374:    *             if(a->r == NULL && !a->fixed && a->on) {
 1375:          
 1376:    *                 if(fabs(a->ix) < 0.005 && fabs(a->iy) < 0.005) {
 1377:    *                     a->ix = 0;
 1378:    *                     a->iy = 0;
 1379:    *                     a->mx = 0;
 1380:    *                     a->my = 0;
 1381:                      }
 1382:          
 1383:    *                 a->x += (a->ix + a->mx) * a->rmdt;
 1384:    *                 a->y += (a->iy + a->my) * a->rmdt;
 1385:          
 1386:    *                 a->mx = 0;
 1387:    *                 a->my = 0;
 1388:                      
 1389:    *                 a->ix *= FLUIDFRICTION;
 1390:    *                 a->iy *= FLUIDFRICTION;
 1391:          
 1392:    *                 a->mvt += fabs(a->ix) + fabs(a->iy);
 1393:          
 1394:    *                 if(a->y < waterlevel) {
 1395:    *                     a->iy += GRAVITY;
 1396:    *                     if(a->level == 1 || a->level == 5) {
 1397:    *                         a->iy += 0.2;
 1398:                          }
 1399:                      }
 1400:    *                 else {
 1401:    .                     dif = a->y - waterlevel;
 1402:    .                     if(dif < 10)
 1403:    .                         a->iy -= dif * 0.17 * GRAVITY;
 1404:    .                     else
 1405:    .                         a->iy -= GRAVITY;
 1406:    .                     a->iy *= 0.99;
 1407:    .                     a->ix *= 0.999;
 1408:    .                     if(a->oy < waterlevel - 0.1) {
 1409:    .                         if(numsplashes < 1) {
 1410:    .                             dopanvol(a->x, 0.5);
 1411:    .                             play_sample(splash, vol, pan, 1000, 0);
 1412:    .                             numsplashes++;
 1413:                              }
 1414:                              //void addanimation(BITMAP **newframes, int newnumframes, int newx, int newy, bool trans, float dy, int delay, int rand) {
 1415:    .                         addanimation(splashanim, 6, (int)(a->x) - 4, (int)(a->y) - 2, 0, 0, 1, 1);
 1416:                              
 1417:                              /*
 1418:            0: Nothing interacts with this. Used for debris
 1419:            1: The human player
 1420:            2: The upper part of buildings (that the player cannot walk through)
 1421:            3: The human's bullets
 1422:            4: The lower part of buildings (that the player can walk through)
 1423:            5: Enemy soldiers
 1424:            6: Enemy bullets
 1425:            7: Vehicles
 1426:            8: Corpses
 1427:            9: Acts like bullets (bomb bullets)
 1428:            */
 1429:          
 1430:    .                         if(a->level == 0 || a->level == 3 || a->level == 6 || a->level == 9)
 1431:    .                             a->life = 500;
 1432:                          }
 1433:                      }
 1434:          
 1435:    *                 if(a->x < buf->w && a->x > 0) {
 1436:    *                     if(a->level != 1 && a->level != 5 && a->level != 8) {
 1437:    *                         gy = path[(int)(a->x)];
 1438:    *                         if(a->x - 5 > 0 && a->x - 5 < buf->w - 1) {
 1439:    *                             gl = path[(int)(a->x - 5)];
 1440:                              }
 1441:    *                         else gl = 0;
 1442:    *                         if(a->x + 5 > 0 && a->x + 5 < buf->w - 1) {
 1443:    *                             gr = path[(int)(a->x + 5)];
 1444:                              }
 1445:    *                         else gl = 0;
 1446:                          }
 1447:    *                     else if(a->level != 8) {
 1448:    *                         gy = path[(int)(a->x)] - 5;
 1449:    *                         if(a->x - 5 > 0 && a->x - 5 < buf->w - 1) {
 1450:    *                             gl = path[(int)(a->x - 5)] - 5;
 1451:                              }
 1452:    *                         else gl = 0;
 1453:    *                         if(a->x + 5 > 0 && a->x + 5 < buf->w - 1) {
 1454:    *                             gr = path[(int)(a->x + 5)] - 5;
 1455:                              }
 1456:    *                         else gl = 0;
 1457:                          }
 1458:    *                     else {
 1459:    *                         gy = path[(int)(a->x)] + 5;
 1460:    *                         if(a->x - 5 > 0 && a->x - 5 < buf->w - 1) {
 1461:    *                             gl = path[(int)(a->x - 5)] + 5;
 1462:                              }
 1463:    *                         else gl = 0;
 1464:    *                         if(a->x + 5 > 0 && a->x + 5 < buf->w - 1) {
 1465:    *                             gr = path[(int)(a->x + 5)] + 5;
 1466:                              }
 1467:    *                         else gl = 0;
 1468:                          }
 1469:                      }
 1470:    *                 else {
 1471:    *                     gy = 800;
 1472:    *                     gl = 800;
 1473:    *                     gr = 800;
 1474:                      }
 1475:          
 1476:    *                 if(a->x < 0) {
 1477:    *                     a->x = 1;
 1478:    *                     a->ix = -a->ix * 0.5;
 1479:    *                     gy = 800;
 1480:                      }
 1481:    *                 if(a->x > buf->w - 1) {
 1482:    .                     a->x = buf->w - 1;
 1483:    .                     a->ix = -a->ix * 0.5;
 1484:                      }       
 1485:    *                 if(a->y < 0) {
 1486:    *                     a->y = 1;
 1487:                          //a->iy = 0;
 1488:    *                     a->ix = a->ix * 0.1;
 1489:    *                     a->iy = -a->iy * 0.1;
 1490:                      }
 1491:          
 1492:    *                 debris = false;
 1493:                      
 1494:    *                 if(a->debris == true && a->d->accrue == true) {
 1495:    *                     dy = debrislev[(int)a->x];
 1496:    *                     if(a->debris == true && a->y >= dy) {                       
 1497:    *                         if(a->y > dy + 2) {
 1498:    *                             a->y--;
 1499:    *                             a->iy = 0;
 1500:                              }
 1501:    *                         else {
 1502:    *                             if(a->x > 1) {
 1503:    *                                 dl = debrislev[(int)a->x - 1];
 1504:                                  }
 1505:    *                             else {
 1506:    .                                 dl = 0;
 1507:                                  }
 1508:    *                             if(a->x < buf->w - 1) {
 1509:    *                                 dr = debrislev[(int)a->x + 1];
 1510:                                  }
 1511:    *                             else {
 1512:    .                                 dr = 0;
 1513:                                  }
 1514:          
 1515:    *                             if(dl > dy) {
 1516:    *                                 a->x -= rand() % 4 + 1;
 1517:    *                                 a->mx = 0;
 1518:    *                                 a->my = 0;
 1519:    *                                 a->ix = 0;
 1520:    *                                 a->iy = 0;
 1521:                                  }
 1522:    *                             else if(dr > dy) {
 1523:    *                                 a->x += rand() % 4 + 1;
 1524:    *                                 a->mx = 0;
 1525:    *                                 a->my = 0;
 1526:    *                                 a->ix = 0;
 1527:    *                                 a->iy = 0;
 1528:                                  }
 1529:    *                             else {
 1530:    *                                 draw_sprite(bg, a->bmp, a->x - 5, a->y - 5);
 1531:    *                                 draw_sprite(buf, a->bmp, a->x - 5, a->y - 5);
 1532:                                      int nx;
 1533:          
 1534:    *                                 if(!a->transdeb) {
 1535:    .                                     for(j = 0; j < 10; j++) {
 1536:    .                                         nx = j + (int)a->x - 5;
 1537:    .                                         if(nx >= 0 && nx < buf->w - 1) {
 1538:    .                                             debrislev[j + (int)a->x - 5] = (int)a->y - (15 - abs(5- j));
 1539:                                              }
 1540:    .                                     }
 1541:                                          
 1542:    .                                     if(dy == gy - 7) {
 1543:                                              BITMAP *tmp;
 1544:                                              int py, pyr;
 1545:    .                                         tmp = create_bitmap(60, 60);
 1546:    .                                         blit(bg, tmp, a->x - 27, a->y - 19, 0, 0, 60, 60);
 1547:    .                                         draw_trans_sprite(tmp, scorch, 0, 0);
 1548:    .                                         for(int xp = 0; xp < 60; xp++) {
 1549:    .                                             nx = (int)xp + (int)a->x - 27;
 1550:    .                                             if(nx > 0 && nx < buf->w - 1) {
 1551:    .                                                 py = path[(int)xp + (int)a->x - 27] + 1;
 1552:    .                                                 pyr = py - a->y + 20 + 1;
 1553:    .                                                 blit(tmp, bg, xp, pyr, xp + a->x - 27, py, 1, 60 - pyr);
 1554:    .                                                 blit(tmp, buf, xp, pyr, xp + a->x - 27, py, 1, 60 - pyr);
 1555:                                                  }
 1556:                                                  //blit(tmp, buf, xp, 0, xp + a->x - 27, a->y - 20, 1, path[(int)xp] - (a->y - 22));
 1557:    .                                         }
 1558:    .                                         destroy_bitmap(tmp);
 1559:    .                                         tmp = NULL;
 1560:                                          }
 1561:                                      }
 1562:                                      
 1563:    *                                 a->on = false;
 1564:    *                                 a->d->kill();
 1565:    *                                 destroyatom(a);
 1566:    *                                 debris = true;
 1567:                                  }
 1568:                              }
 1569:                          }
 1570:                      }
 1571:    *                 else if(a->debris && a->y > gy) {
 1572:    *                     a->on = false;
 1573:    *                     a->d->kill();
 1574:    *                     destroyatom(a);
 1575:    *                     debris = true;
 1576:                      }
 1577:          
 1578:    *                 if (!debris) {
 1579:          
 1580:    *                     if(a->y > gy) { //gy) {
 1581:    *                         a->y = gy;
 1582:    *                         if(a->damage != NULL) {
 1583:    *                             dmg = fabs(a->iy) - 13;
 1584:    *                             if(fabs(a->ix) > 5) dmg += a->ix - 5;
 1585:    *                             if(dmg > 0) {
 1586:    *                                 *(a->damage) += 1 * dmg;
 1587:                                  }
 1588:                              }
 1589:    *                         a->iy = -a->iy * 0.1;
 1590:                          }
 1591:          
 1592:    *                     if(a->y > gy - 5) {
 1593:    *                         if(a->level != 1 && a->level != 5) {
 1594:    *                             if(gl < gy && gr > gy) {
 1595:    *                                 a->ix += (a->y - gy + 10) * .002;
 1596:                                  }
 1597:    *                             else if(gl > gy && gr < gy) {
 1598:    *                                 a->ix -= (a->y - gy + 10) * .002;
 1599:                                  }
 1600:    *                             a->ix *= 0.9;
 1601:                              }
 1602:    *                         else {
 1603:    *                             if(gl < gy && gr > gy && (a->ix < -0.2 || a->ix > 0.2)) {
 1604:    *                                 if(a->ix < -0.5 || a->ix > 0.5)
 1605:    *                                     a->mx = .2;
 1606:                                  }
 1607:    *                             else if(gl > gy && gr < gy && (a->ix < -0.2 || a->ix > 0.2)) {
 1608:    *                                 a->mx = -.2;
 1609:                                  }
 1610:    *                             a->ix *= 0.995;
 1611:                              }
 1612:                          }
 1613:          
 1614:    *                     nbx = ((int)(a->x) / 10) + 2;
 1615:    *                     nby = ((int)(a->y) / 10) + 2;
 1616:          
 1617:    *                     if(nbx != a->bx || nby != a->by) {
 1618:          
 1619:    *                         b = &(boxes[a->bx][a->by]);
 1620:    *                         j = 0;
 1621:    *                         b->count--;
 1622:    *                         while(j < b->count && b->list[j] != a) j++;
 1623:    *                         b->list[j] = b->list[b->count];
 1624:          
 1625:    *                         b = &(boxes[nbx][nby]);
 1626:    *                         if(b->count < 45) {
 1627:    *                             b->list[b->count] = a;
 1628:    *                             b->count++;
 1629:                              }
 1630:    *                         a->bx = nbx;
 1631:    *                         a->by = nby;
 1632:                          }
 1633:                      }
 1634:                  }
 1635:    *             a++;
 1636:    *         }
 1637:    *     }
 1638:          
 1639:          
 1640:          
 1641:          
 1642:          
 1643:          //                  **ACTUAL PROGRAM**
 1644:          
 1645:    *     void setupforcetable() {
 1646:              int x, y;
 1647:              float dist, dx, dy;
 1648:              float force, fx, fy;
 1649:              
 1650:    *         for(x = 0; x < 20; x++) {
 1651:    *             for(y = 0; y < 20; y++) {
 1652:    *                 dx = x - 10;
 1653:    *                 dy = y - 10;
 1654:    *                 dist = (float)(sqrt(dx * dx + dy * dy));
 1655:    *                 if(dist <= 10) {
 1656:    *                     force = (10 - dist) * REPULSESTRENGTH;
 1657:    *                     fx = (dx / dist) * force;
 1658:    *                     fy = (dy / dist) * force;
 1659:    *                     forcetable_repulse_x[x][y] = fx;
 1660:    *                     forcetable_repulse_y[x][y] = fy;
 1661:                      }
 1662:    *                 else {
 1663:    *                     forcetable_repulse_x[x][y] = 0;
 1664:    *                     forcetable_repulse_y[x][y] = 0;
 1665:                      }
 1666:    *             }
 1667:    *         }
 1668:    *     }
 1669:          
 1670:    *     void physics_initvars() {
 1671:    *         debug = fopen("debug.txt", "w");
 1672:    *         setbuf(debug, NULL);
 1673:          
 1674:    *         DIAGRL = sqrt(200);
 1675:    *         DIAGBP = BPMULT * DIAGRL; //- 0;
 1676:    *         STRBP = BPMULT * 10.0 + 0.4;
 1677:    *         numatoms = 0;
 1678:    *         numpolys = 0;
 1679:    *         numobjects = 0;
 1680:    *         expc = 0;
 1681:          
 1682:    *         setupforcetable();
 1683:    *     }
 1684:          
 1685:    .     void initializeold() {
 1686:              int i, nbx, nby;
 1687:    .         for(i = 0; i < MAXATOMS; i = i + 1) {
 1688:    .             atoms[i].x = (float)(rand() % 300);
 1689:    .             atoms[i].y = (float)(rand() % 600);
 1690:    .             nbx = (int)(((int)atoms[i].x / 10) + 2);
 1691:    .             nby = (int)(((int)atoms[i].y / 10) + 2);
 1692:    .             boxes[nbx][nby].list[boxes[nbx][nby].count] = &(atoms[i]);
 1693:    .             boxes[nbx][nby].count++;
 1694:    .             atoms[i].bx = nbx;
 1695:    .             atoms[i].by = nby;
 1696:    .             atoms[i].rmdt = 1;
 1697:    .         }
 1698:          
 1699:    .         atoms[0].x = 100;
 1700:    .         atoms[0].y = 500;
 1701:    .         atoms[1].x = 110;
 1702:    .         atoms[1].y = 500;
 1703:    .         atoms[2].x = 110;
 1704:    .         atoms[2].y = 510;
 1705:    .         atoms[3].x = 100;
 1706:    .         atoms[3].y = 510;
 1707:    .         addlink(&(atoms[0]), &(atoms[1]), 10, STRBP);
 1708:    .         addlink(&(atoms[1]), &(atoms[2]), 10, STRBP);
 1709:    .         addlink(&(atoms[2]), &(atoms[3]), 10, STRBP);
 1710:    .         addlink(&(atoms[3]), &(atoms[0]), 10, STRBP);
 1711:          
 1712:    .         addlink(&(atoms[0]), &(atoms[2]), DIAGRL, DIAGBP);
 1713:    .         addlink(&(atoms[1]), &(atoms[3]), DIAGRL, DIAGBP);
 1714:    .     }
 1715:          
 1716:    *     int shouldbeatom(BITMAP *obj, int x, int y) {
 1717:          
 1718:    *         bool mag = false;
 1719:    *         bool omag = false;
 1720:          
 1721:    *         for(int xp = x - PIXW; xp < x + PIXW; xp++) {
 1722:    *             for(int yp = y - PIXW; yp < y + PIXW; yp++) {
 1723:    *                 if(xp >= 0 && yp >= 0 && xp < obj->w && yp < obj->h) {
 1724:    *                     if(getpixel(obj, xp, yp) != magenta) {
 1725:    *                         omag = true;
 1726:                          }
 1727:    *                     else {
 1728:    *                         mag = true;
 1729:                          }
 1730:                      }
 1731:    *             }
 1732:    *         }
 1733:          
 1734:    *         if(omag && mag) return 2;
 1735:    *         else if(omag) return 1;
 1736:    *         else return 0;
 1737:              return 0;
 1738:    *     }
 1739:          
 1740:    *     void dotex(poly *r, BITMAP **obj, BITMAP **transmap, int x1, int y1, int x2, int y2, int x3, int y3) {
 1741:              V3D_f *a, *b, *c;
 1742:    *         a = new V3D_f;
 1743:    *         b = new V3D_f;
 1744:    *         c = new V3D_f;
 1745:          
 1746:    *         a->u = x1;
 1747:    *         a->v = y1;
 1748:    *         b->u = x2;
 1749:    *         b->v = y2;
 1750:    *         c->u = x3;
 1751:    *         c->v = y3;
 1752:          
 1753:    *         a->c = b->c = c->c = 2;
 1754:    *         a->z = b->z = c->z = 10;
 1755:          
 1756:    *         r->v1 = a;
 1757:    *         r->v2 = b;
 1758:    *         r->v3 = c;
 1759:    *         r->tmap = obj;
 1760:    *         if(*transmap == NULL) {
 1761:    *             r->transmap = NULL;
 1762:              }
 1763:    *         else
 1764:    *             r->transmap = transmap;
 1765:          
 1766:              /*
 1767:              if(r->trans == true) {
 1768:                  r->thold = create_bitmap(15, 15);
 1769:                  clear_to_color(r->thold, 0);
 1770:              }
 1771:              */
 1772:    *     }
 1773:          
 1774:    *     void checktransdeb(atom *a) {
 1775:              int x, y;
 1776:    *         bool mag = false;
 1777:    *         for(x = 0; x < a->bmp->w; x++) {
 1778:    *             for(y = 0; y < a->bmp->h; y++) {
 1779:    *                 if(getpixel(a->bmp, x, y) == magenta) {
 1780:    *                     mag = true;
 1781:    *                     break;
 1782:                      }
 1783:    *             }
 1784:    *         }
 1785:    *         if(!mag)
 1786:    *             a->transdeb = false;
 1787:    *         else
 1788:    *             a->transdeb = true;
 1789:    *     }
 1790:          
 1791:    *     void addobject(char *fn, char *fnt, float startx, float starty, bool fixed, bool levels[MAXLEVELS], int level, float lmod) {
 1792:              int x, y;
 1793:              poly *r;
 1794:              object *o;
 1795:    *         int v, maxy = 0;
 1796:              atom *a;
 1797:          
 1798:    *         o = &(objects[numobjects]);
 1799:    *         numobjects++;
 1800:    *         o->obj = load_bitmap(fn, NULL);
 1801:    *         if(fnt != NULL) {
 1802:    *             o->transmap = load_bitmap(fnt, NULL);
 1803:              }
 1804:    *         else {      
 1805:    *             o->transmap = NULL;
 1806:              }
 1807:    *         o->origobj = o->obj;
 1808:          
 1809:    *         for(x = 0; x < 100; x++) {
 1810:    *             for(y = 0; y < 100; y++) {
 1811:    *                 v = shouldbeatom(o->obj, x * 10, y * 10);
 1812:    *                 if(v != 0) {
 1813:    *                     structure[x][y] = addatom(x * 10 + startx, y * 10 + starty, levels, level);
 1814:    *                     a = structure[x][y];
 1815:    *                     a->draw = false;
 1816:                          /*
 1817:                          if(v == 2)
 1818:                              a->draw2 = false;
 1819:                          else
 1820:                              a->draw2 = true;
 1821:                          */
 1822:    *                     a->bmp = create_bitmap(14, 14);
 1823:    *                     clear_to_color(a->bmp, magenta);
 1824:    *                     blit(o->obj, a->bmp, x * 10 - 7, y * 10 - 7, 0, 0, 14, 14);
 1825:    *                     checktransdeb(a);
 1826:    *                     if(!a->transdeb) {
 1827:    *                         draw_trans_sprite(a->bmp, debris1, 0, 0);
 1828:                          }
 1829:    *                     else {
 1830:                              int x, y, r1, g1, b1, r2, g2, b2, rf, gf, bf;
 1831:    *                         r2 = 40;
 1832:    *                         g2 = 40;
 1833:    *                         b2 = 40;
 1834:                              int dist, gd;
 1835:    *                         float al = .5;
 1836:    *                         for(x = 0; x < a->bmp->w; x++) {
 1837:    *                             for(y = 0; y < a->bmp->h; y++) {
 1838:    *                                 if(getpixel(a->bmp, x, y) != magenta) {
 1839:    *                                     r1 = getr(getpixel(a->bmp, x, y));
 1840:    *                                     g1 = getg(getpixel(a->bmp, x, y));
 1841:    *                                     b1 = getb(getpixel(a->bmp, x, y));
 1842:    *                                     dist = r2 - r1;
 1843:    *                                     gd = al * dist;
 1844:    *                                     rf = r1 + gd;
 1845:    *                                     dist = g2 - g1;
 1846:    *                                     gd = al * dist;
 1847:    *                                     gf = g1 + gd;
 1848:    *                                     dist = b2 - b1;
 1849:    *                                     gd = al * dist;
 1850:    *                                     bf = b1 + gd;
 1851:    *                                     putpixel(a->bmp, x, y, makecol16(rf, gf, bf));
 1852:                                      }
 1853:    *                             }
 1854:    *                         }
 1855:    *                         draw_trans_sprite(a->bmp, debriso1, 0, 0);
 1856:                          }
 1857:                      }
 1858:    *                 else {
 1859:    *                     structure[x][y] = NULL;
 1860:                      }
 1861:    *             }
 1862:    *         }
 1863:          
 1864:    *         for(x = 0; x < 100; x++) {
 1865:    *             for(y = 0; y < 100; y++) {
 1866:    *                 if(structure[x][y] != NULL) {
 1867:    *                     if(x > 0 && structure[x-1][y] != NULL)
 1868:    *                         addlink(structure[x][y], structure[x-1][y], 10, STRBP * lmod);
 1869:    *                     if(y > 0 && structure[x][y-1] != NULL)
 1870:    *                         addlink(structure[x][y], structure[x][y-1], 10, STRBP * lmod);
 1871:                          
 1872:    *                     if(x > 0 && y > 0 && structure[x-1][y-1] != NULL)
 1873:    *                         addlink(structure[x][y], structure[x-1][y-1], DIAGRL, DIAGBP * lmod);
 1874:    *                     if(x < 99 && y > 0 && structure[x+1][y-1] != NULL)
 1875:    *                         addlink(structure[x][y], structure[x+1][y-1], DIAGRL, DIAGBP * lmod);
 1876:                      }
 1877:    *             }
 1878:    *         }
 1879:              
 1880:    *         for(x = 0; x < 99; x++) {
 1881:    *             for(y = 0; y < 99; y++) {
 1882:    *                 if(x - 1 >= 0 && y - 1 >= 0 && structure[x][y] != NULL && structure[x - 1][y] != NULL && structure[x - 1][y - 1] != NULL) {
 1883:    *                     r = addpoly(structure[x][y], structure[x - 1][y], structure[x - 1][y - 1]);//getpixel(o->obj, x * PIXW, y * PIXW));
 1884:    *                     r->type = 0;
 1885:    *                     if(r->a->draw == false && r->b->draw == false && r->c->draw == false) {
 1886:    *                         r->trans = true;
 1887:                          }
 1888:    *                     dotex(r, &(o->obj), &(o->transmap), (x-0) * PIXW, (y-0) * PIXW,(x - 1) * PIXW, (y) * PIXW,(x - 1) * PIXW, (y - 1) * PIXW);
 1889:                      }
 1890:    *                 if(x - 1 >= 0 && y - 1 >= 0 && structure[x][y] != NULL && structure[x - 1][y - 1] != NULL && structure[x][y - 1] != NULL) {
 1891:    *                     r = addpoly(structure[x][y], structure[x - 1][y - 1], structure[x][y - 1]);//getpixel(o->obj, x * PIXW, y * PIXW));
 1892:    *                     r->type = 1;
 1893:    *                     if(r->a->draw == false && r->b->draw == false && r->c->draw == false) {
 1894:    *                         r->trans = true;
 1895:                          }
 1896:    *                     dotex(r, &(o->obj), &(o->transmap), (x-0) * PIXW, (y-0) * PIXW,(x - 1) * PIXW, (y - 1) * PIXW,(x) * PIXW, (y - 1) * PIXW);
 1897:                      }
 1898:                      /*
 1899:                      //if(x == 1 && y == 2) {
 1900:                      if(y - 1 >= 0 && structure[x][y] != NULL && structure[x][y - 1] != NULL && structure[x + 1][y - 1] != NULL) {
 1901:                          r = addpoly(structure[x][y], structure[x][y - 1], structure[x + 1][y - 1]);//getpixel(o->obj, x * PIXW, y * PIXW));
 1902:                          if(r->a->draw == false && r->b->draw == false && r->c->draw == false) {
 1903:                              r->trans = true;
 1904:                          }
 1905:                          dotex(r, &(o->obj), (x-0) * PIXW, (y-0) * PIXW,(x) * PIXW, (y - 1) * PIXW,(x + 1) * PIXW, (y - 1) * PIXW);
 1906:                      }
 1907:                      if(y - 1 >= 0 && structure[x][y] != NULL && structure[x + 1][y - 1] != NULL && structure[x + 1][y] != NULL) {
 1908:                          r = addpoly(structure[x][y], structure[x + 1][y - 1], structure[x + 1][y]);//getpixel(o->obj, x * PIXW, y * PIXW));
 1909:                          if(r->a->draw == false && r->b->draw == false && r->c->draw == false) {
 1910:                              r->trans = true;
 1911:                          }
 1912:                          dotex(r, &(o->obj), (x) * PIXW, (y) * PIXW,(x + 1) * PIXW, (y - 1) * PIXW,(x + 1) * PIXW, (y) * PIXW);
 1913:                      }
 1914:                      */
 1915:    *             }
 1916:    *         }
 1917:          
 1918:    *         for(y = 0; y < 100; y++) {
 1919:    *             for(x = 0; x < 100; x++) {
 1920:    *                 if(structure[x][y] != NULL) {
 1921:    *                     maxy = y;
 1922:    *                     x = 100;
 1923:                      }
 1924:    *             }
 1925:    *         }
 1926:          
 1927:    *         if(strcmp(fn, "building.pcx") == 0 || strcmp(fn, "building2.pcx") == 0 || strcmp(fn, "building3.pcx") == 0 || strcmp(fn, "building4.pcx") == 0) {
 1928:    *             for(x = 0; x < 50; x++) {
 1929:    *                 for(y = maxy; y > maxy - 5; y--) {
 1930:    *                     if(structure[x][y] != NULL) {
 1931:    *                         structure[x][y]->levels[1] = false;
 1932:    *                         structure[x][y]->levels[5] = false;
 1933:    *                         structure[x][y]->levels[11] = false;
 1934:    *                         structure[x][y]->levels[12] = false;
 1935:    *                         structure[x][y]->level = 4;
 1936:                          }
 1937:    *                 }
 1938:    *             }
 1939:              }
 1940:          
 1941:    *         if(fixed) {
 1942:    *             for(x = 0; x < 50; x++) {
 1943:    *                 if(structure[x][maxy] != NULL) {
 1944:    *                     structure[x][maxy]->fixed = true;
 1945:    *                     structure[x][maxy]->draw = false;
 1946:                      }
 1947:    *             }
 1948:              }
 1949:    *     }
 1950:          
 1951:    *     rigidbody *addrigidobject(char *fn, float startx, float starty, bool fixed, bool levels[MAXLEVELS], int level, float rm, float ram, float gmult, float bpmult) {
 1952:              int x, y;
 1953:              poly *r;
 1954:              object *o;
 1955:    *         int v, maxy = 0;
 1956:              atom *a;
 1957:              rigidbody *rb;
 1958:              float *structurex[100][100];
 1959:              float *structurey[100][100];
 1960:          
 1961:    *         o = &(objects[numobjects]);
 1962:    *         numobjects++;
 1963:              //fprintf(debug, "o:%i\n", o->obj);
 1964:    *         o->obj = load_bitmap(fn, NULL);
 1965:    *         o->transmap = NULL;
 1966:              //fprintf(debug, "o:%i\n", o->obj);
 1967:    *         o->origobj = o->obj;
 1968:          
 1969:    *         rb = addrigidbody(rm, ram, gmult);
 1970:          
 1971:    *         for(x = 0; x < 100; x++) {
 1972:    *             for(y = 0; y < 100; y++) {
 1973:    *                 v = shouldbeatom(o->obj, x * 10, y * 10);
 1974:    *                 if(v != 0) {
 1975:    *                     structure[x][y] = addatom(x * 10 + startx, y * 10 + starty, levels, level);
 1976:    *                     a = structure[x][y];
 1977:    *                     rb->addatom(a);
 1978:    *                     structurex[x][y] = &(rb->polylistx[rb->mynumpolys]);
 1979:    *                     structurey[x][y] = &(rb->polylisty[rb->mynumpolys]);
 1980:    *                     rb->mynumpolys++;
 1981:    *                     if(v == 2) {
 1982:    *                         a->draw = false;
 1983:                          }
 1984:    *                     a->bmp = create_bitmap(14, 14);
 1985:    *                     clear_to_color(a->bmp, magenta);
 1986:    *                     blit(o->obj, a->bmp, x * 10 - 7, y * 10 - 7, 0, 0, 14, 14);
 1987:    *                     checktransdeb(a);
 1988:    *                     if(!a->transdeb) {
 1989:                              BITMAP *tmp;
 1990:    .                         tmp = load_bitmap("debris1.tga", NULL);
 1991:    .                         draw_trans_sprite(a->bmp, tmp, 0, 0);
 1992:                          }
 1993:    .                     else {
 1994:                              int x, y, r1, g1, b1, r2, g2, b2, rf, gf, bf;
 1995:    *                         r2 = 40;
 1996:    *                         g2 = 40;
 1997:    *                         b2 = 40;
 1998:                              int dist, gd;
 1999:    *                         float al = .5;
 2000:    *                         for(x = 0; x < a->bmp->w; x++) {
 2001:    *                             for(y = 0; y < a->bmp->h; y++) {
 2002:    *                                 if(getpixel(a->bmp, x, y) != magenta) {
 2003:    *                                     r1 = getr(getpixel(a->bmp, x, y));
 2004:    *                                     g1 = getg(getpixel(a->bmp, x, y));
 2005:    *                                     b1 = getb(getpixel(a->bmp, x, y));
 2006:    *                                     dist = r2 - r1;
 2007:    *                                     gd = al * dist;
 2008:    *                                     rf = r1 + gd;
 2009:    *                                     dist = g2 - g1;
 2010:    *                                     gd = al * dist;
 2011:    *                                     gf = g1 + gd;
 2012:    *                                     dist = b2 - b1;
 2013:    *                                     gd = al * dist;
 2014:    *                                     bf = b1 + gd;
 2015:    *                                     putpixel(a->bmp, x, y, makecol16(rf, gf, bf));
 2016:                                      }
 2017:    *                             }
 2018:    *                         }
 2019:    *                         draw_trans_sprite(a->bmp, debriso1, 0, 0);
 2020:                          }
 2021:                      }
 2022:    *                 else {
 2023:    *                     structure[x][y] = NULL;
 2024:                      }
 2025:    *             }
 2026:    *         }
 2027:          
 2028:    *         rb->complete();
 2029:          
 2030:    *         for(x = 0; x < 100; x++) {
 2031:    *             for(y = 0; y < 100; y++) {
 2032:    *                 if(structure[x][y] != NULL) {
 2033:    *                     if(x > 0 && structure[x-1][y] != NULL)
 2034:    *                         addlink(structure[x][y], structure[x-1][y], 10, STRBP * bpmult);
 2035:    *                     if(y > 0 && structure[x][y-1] != NULL)
 2036:    *                         addlink(structure[x][y], structure[x][y-1], 10, STRBP * bpmult);
 2037:    *                     if(x > 0 && y > 0 && structure[x-1][y-1] != NULL)
 2038:    *                         addlink(structure[x][y], structure[x-1][y-1], DIAGRL, DIAGBP * bpmult);
 2039:    *                     if(x < 99 && y > 0 && structure[x+1][y-1] != NULL)
 2040:    *                         addlink(structure[x][y], structure[x+1][y-1], DIAGRL, DIAGBP * bpmult);
 2041:                      }
 2042:    *             }
 2043:    *         }
 2044:              
 2045:    *         rb->mynumpolys = 0;
 2046:    *         for(x = 0; x < 99; x++) {
 2047:    *             for(y = 0; y < 99; y++) {
 2048:    *                 if(x - 1 >= 0 && y - 1 >= 0 && structure[x][y] != NULL && structure[x - 1][y] != NULL && structure[x - 1][y - 1] != NULL) {
 2049:    *                     r = addpoly(structure[x][y], structure[x - 1][y], structure[x - 1][y - 1]);//getpixel(o->obj, x * PIXW, y * PIXW));
 2050:    *                     r->ax = structurex[x][y];
 2051:    *                     r->ay = structurey[x][y];
 2052:    *                     r->bx = structurex[x-1][y];
 2053:    *                     r->by = structurey[x-1][y];
 2054:    *                     r->cx = structurex[x-1][y-1];
 2055:    *                     r->cy = structurey[x-1][y-1];
 2056:    *                     rb->addpoly(r);
 2057:    *                     if(r->a->draw == false && r->b->draw == false && r->c->draw == false) {
 2058:    *                         r->trans = true;
 2059:                          }
 2060:    *                     dotex(r, &(o->obj), &(o->transmap), (x-0) * PIXW, (y-0) * PIXW,(x - 1) * PIXW, (y) * PIXW,(x - 1) * PIXW, (y - 1) * PIXW);
 2061:                      }
 2062:    *                 if(x - 1 >= 0 && y - 1 >= 0 && structure[x][y] != NULL && structure[x - 1][y - 1] != NULL && structure[x][y - 1] != NULL) {
 2063:    *                     r = addpoly(structure[x][y], structure[x - 1][y - 1], structure[x][y - 1]);//getpixel(o->obj, x * PIXW, y * PIXW));
 2064:    *                     r->ax = structurex[x][y];
 2065:    *                     r->ay = structurey[x][y];
 2066:    *                     r->bx = structurex[x-1][y-1];
 2067:    *                     r->by = structurey[x-1][y-1];
 2068:    *                     r->cx = structurex[x][y-1];
 2069:    *                     r->cy = structurey[x][y-1];
 2070:    *                     rb->addpoly(r);
 2071:    *                     if(r->a->draw == false && r->b->draw == false && r->c->draw == false) {
 2072:    *                         r->trans = true;
 2073:                          }
 2074:    *                     dotex(r, &(o->obj), &(o->transmap), (x-0) * PIXW, (y-0) * PIXW,(x - 1) * PIXW, (y - 1) * PIXW,(x) * PIXW, (y - 1) * PIXW);
 2075:                      }
 2076:                      //if(x == 1 && y == 2) {
 2077:    *                 if(y - 1 >= 0 && structure[x + 1][y] == NULL && structure[x][y] != NULL && structure[x][y - 1] != NULL && structure[x + 1][y - 1] != NULL) {
 2078:    .                     r = addpoly(structure[x][y], structure[x][y - 1], structure[x + 1][y - 1]);//getpixel(o->obj, x * PIXW, y * PIXW));             
 2079:    .                     r->ax = structurex[x][y];
 2080:    .                     r->ay = structurey[x][y];
 2081:    .                     r->bx = structurex[x][y-1];
 2082:    .                     r->by = structurey[x][y-1];
 2083:    .                     r->cx = structurex[x+1][y-1];
 2084:    .                     r->cy = structurey[x+1][y-1];
 2085:    .                     rb->addpoly(r);
 2086:    .                     if(r->a->draw == false && r->b->draw == false && r->c->draw == false) {
 2087:    .                         r->trans = true;
 2088:                          }
 2089:    .                     dotex(r, &(o->obj), &(o->transmap), (x-0) * PIXW, (y-0) * PIXW,(x) * PIXW, (y - 1) * PIXW,(x + 1) * PIXW, (y - 1) * PIXW);
 2090:                      }
 2091:    *                 if(y - 1 >= 0 && structure[x][y - 1] == NULL && structure[x][y] != NULL && structure[x + 1][y - 1] != NULL && structure[x + 1][y] != NULL) {
 2092:    *                     r = addpoly(structure[x][y], structure[x + 1][y - 1], structure[x + 1][y]);//getpixel(o->obj, x * PIXW, y * PIXW));
 2093:    *                     r->ax = structurex[x][y];
 2094:    *                     r->ay = structurey[x][y];
 2095:    *                     r->bx = structurex[x+1][y-1];
 2096:    *                     r->by = structurey[x+1][y-1];
 2097:    *                     r->cx = structurex[x+1][y];
 2098:    *                     r->cy = structurey[x+1][y];
 2099:    *                     rb->addpoly(r);
 2100:    *                     if(r->a->draw == false && r->b->draw == false && r->c->draw == false) {
 2101:    *                         r->trans = true;
 2102:                          }
 2103:    *                     dotex(r, &(o->obj), &(o->transmap), (x) * PIXW, (y) * PIXW,(x + 1) * PIXW, (y - 1) * PIXW,(x + 1) * PIXW, (y) * PIXW);
 2104:                      }
 2105:    *             }
 2106:    *         }
 2107:          
 2108:    *         for(y = 0; y < 100; y++) {
 2109:    *             for(x = 0; x < 100; x++) {
 2110:    *                 if(structure[x][y] != NULL) {
 2111:    *                     maxy = y;
 2112:    *                     x = 100;
 2113:                      }
 2114:    *             }
 2115:    *         }
 2116:          
 2117:    *         if(strcmp(fn, "building.pcx") == 0) {
 2118:    .             for(x = 0; x < 50; x++) {
 2119:    .                 for(y = maxy; y > maxy - 5; y--) {
 2120:    .                     if(structure[x][y] != NULL) {
 2121:    .                         structure[x][y]->levels[1] = false;
 2122:    .                         structure[x][y]->level = 4;
 2123:                          }
 2124:    .                 }
 2125:    .             }
 2126:              }
 2127:          
 2128:    *         if(fixed) {
 2129:    .             for(x = 0; x < 50; x++) {
 2130:    .                 if(structure[x][maxy] != NULL) {
 2131:    .                     structure[x][maxy]->fixed = true;
 2132:    .                     structure[x][maxy]->draw = false;
 2133:                      }
 2134:    .             }
 2135:              }
 2136:          
 2137:    *         return rb;
 2138:    *     }
 2139:          
 2140:    .     void addbox() {
 2141:              bool levels[MAXLEVELS];
 2142:    .         for(int i = 0; i < MAXLEVELS; i++) {
 2143:    .             levels[i] = true;
 2144:    .         }
 2145:    .         levels[0] = false;
 2146:              //levels[1] = false;
 2147:              
 2148:    .         addobject("building.pcx", "buildingt.tga", 200, 200, false, levels, 2, 1);
 2149:    .     }
 2150:          
 2151:    *     void physics_initialize() {
 2152:    *         thold = create_bitmap(15, 15);
 2153:    *         tmp = create_bitmap_ex(32, 40, 40);
 2154:    *         clear_to_color(thold, 0);
 2155:    *     }
 2156:          
 2157:    *     void drawatoms() {
 2158:              int i;
 2159:              atom *a;
 2160:                  
 2161:    *         a = &(atoms[0]);
 2162:    *         for(i = 0; i < numatoms; i++) {
 2163:    *             if(a->draw && a->on) {
 2164:    *                 putpixel(buf, a->x, a->y, a->color);
 2165:                  }
 2166:    *             a++;
 2167:    *         }
 2168:    *     }
 2169:          
 2170:    *     void drawlinks() {
 2171:              int i;
 2172:              link *l;
 2173:          
 2174:    *         l = &(links[0]);
 2175:    *         for(i = 0; i < numlinks; i++) {
 2176:    *             if(l->on && l->draw && ((l->a->x > lx && l->a->x < rx) || (l->b->x > lx && l->b->x < rx))) {
 2177:    *                 line(buf, l->a->x, l->a->y, l->b->x, l->b->y, l->color);
 2178:    *                 l->drew = true;
 2179:                  }
 2180:    *             l++;
 2181:    *         }
 2182:    *     }
 2183:          
 2184:    *     void cleanline(BITMAP *bmp, int x, int y, int d) {
 2185:    *         putpixel(buf, x, y, getpixel(bg, x, y));
 2186:    *     }
 2187:          
 2188:    *     void eraselinks() {
 2189:              link *l;
 2190:              int i;
 2191:              
 2192:    *         l = &(links[0]);
 2193:    *         for(i = 0; i < numlinks; i++) {
 2194:    *             if(l->drew && l->draw && l->on) {
 2195:    *                 do_line(buf, l->a->x, l->a->y, l->b->x, l->b->y, 0, cleanline);
 2196:    *                 l->drew = false;
 2197:                  }
 2198:    *             l++;
 2199:    *         }
 2200:    *     }
 2201:          
 2202:          /*
 2203:          void eraselinks() {
 2204:              int i;
 2205:              link *l;
 2206:          
 2207:              l = &(links[0]);
 2208:              for(i = 0; i < numlinks; i++) {
 2209:                  if(l->on && l->draw) {
 2210:                      line(buf, l->a->x, l->a->y, l->b->x, l->b->y, black);
 2211:                  }
 2212:                  l++;
 2213:              }
 2214:          }
 2215:          */
 2216:          
 2217:    *     void drawpolys() {
 2218:              poly *p;
 2219:              int i;
 2220:          
 2221:    *         p = &(polys[0]);
 2222:          
 2223:    *         for(i = 0; i < numpolys; i++) {
 2224:    *             if(p->on && ((p->a->x > lx && p->a->x < rx) || (p->b->x > lx && p->b->x < rx) || (p->c->x > lx && p->c->x < rx))) {
 2225:                      if(p->trans == false && 0
 2226:                          //|| 1
 2227:    *                     ) {
 2228:                          
 2229:    .                     p->v1->x = *p->ax;
 2230:    .                     p->v1->y = *p->ay;
 2231:    .                     p->v2->x = *p->bx;
 2232:    .                     p->v2->y = *p->by;
 2233:    .                     p->v3->x = *p->cx;
 2234:    .                     p->v3->y = *p->cy;
 2235:                          
 2236:                          //draw_sprite(buf, p->tmap, 50, 50);
 2237:          
 2238:    .                     triangle3d_f(buf, POLYTYPE_ATEX, *(p->tmap), p->v1, p->v2, p->v3);
 2239:                      }
 2240:    .                 else {
 2241:    *                     clear_to_color(thold, magenta);
 2242:          
 2243:                          double lowx, lowy;
 2244:                          
 2245:    *                     lowx = findlow(*p->ax, *p->bx, *p->cx);
 2246:    *                     lowy = findlow(*p->ay, *p->by, *p->cy);
 2247:                          
 2248:    *                     p->v1->x = *p->ax - lowx;
 2249:    *                     p->v1->y = *p->ay - lowy;
 2250:          
 2251:    *                     p->v2->x = *p->bx - lowx;
 2252:    *                     p->v2->y = *p->by - lowy;
 2253:          
 2254:    *                     p->v3->x = *p->cx - lowx;
 2255:    *                     p->v3->y = *p->cy - lowy;
 2256:          
 2257:    *                     triangle3d_f(thold, POLYTYPE_ATEX, *(p->tmap), p->v1, p->v2, p->v3);
 2258:    *                     draw_sprite(buf, thold, lowx, lowy);
 2259:                      }
 2260:    *                 p->drew = true;
 2261:                  }
 2262:    *             p++;
 2263:    *         }
 2264:    *     }
 2265:          
 2266:    *     void erasepolys() {
 2267:              int lowx, lowy, highx, highy;
 2268:              poly *p;
 2269:              int i;
 2270:          
 2271:    *         p = &(polys[0]);
 2272:          
 2273:    *         for(i = 0; i < numpolys; i++) {
 2274:    *             if(p->on && p->drew) {
 2275:    *                 lowx = findlow(p->a->x, p->b->x, p->c->x);
 2276:    *                 lowy = findlow(p->a->y, p->b->y, p->c->y);
 2277:    *                 highx = findhigh(p->a->x, p->b->x, p->c->x);
 2278:    *                 highy = findhigh(p->a->y, p->b->y, p->c->y);
 2279:          
 2280:                      //rectfill(buf, lowx, lowy, highx, highy, black);
 2281:    *                 blit(bg, buf, lowx, lowy, lowx, lowy, highx - lowx, highy - lowy);
 2282:    *                 p->drew = false;
 2283:                  }
 2284:    *             p++;
 2285:    *         }
 2286:    *     }
 2287:          
 2288:    *     void reset() {
 2289:              int x, y, i;
 2290:    *         for(x = 0; x < MAXBOXX; x++) {
 2291:    *             for(y = 0; y < MAXBOXY; y++) {
 2292:    *                 boxes[x][y].count = 0;
 2293:    *                 for(int z = 0; z < 50; z++) {
 2294:    *                     boxes[x][y].list[z] = NULL;
 2295:    *                 }
 2296:    *             }
 2297:    *         }
 2298:    *         for(i = 0; i < numatoms; i++) {
 2299:    *             atoms[i].ix = atoms[i].iy = 0;
 2300:    *             atoms[i].lc = 0;
 2301:    *             atoms[i].fixed = false;
 2302:    *             atoms[i].on = false;
 2303:    *             destroyatom(&(atoms[i]));
 2304:    *             if(atoms[i].bmp != NULL) {
 2305:    .                 destroy_bitmap(atoms[i].bmp);
 2306:    .                 atoms[i].bmp = NULL;
 2307:                  }
 2308:    *             atoms[i].init();
 2309:    *         }
 2310:    *         numatoms = 0;
 2311:    *         for(i = 0; i < numpolys; i++) {
 2312:    *             polys[i].on = false;
 2313:    *             polys[i].init();
 2314:    *         }
 2315:    *         numpolys = 0;
 2316:    *         for(i = 0; i < numlinks; i++) {
 2317:    *             links[i].on = false;
 2318:    *             links[i].init();
 2319:    *         }
 2320:    *         numlinks = 0;
 2321:    *         for(i = 0; i < numrigidbodies; i++) {
 2322:    *             rigidbodies[i].on = false;
 2323:    *             rigidbodies[i].init();
 2324:    *         }
 2325:    *         numrigidbodies = 0;
 2326:    *         for(i = 0; i < numobjects; i++) {
 2327:    *             objects[i].reset();
 2328:    *         }
 2329:    *         numobjects = 0;
 2330:    *         physics_initialize();
 2331:    *     }
 2332:          
 2333:    *     void eraseatoms() {
 2334:              int i;
 2335:              atom *a;
 2336:              
 2337:    *         a = &(atoms[0]);
 2338:    *         for(i = 0; i < numatoms; i++) {
 2339:    *             if(a->draw && a->on)
 2340:    *                 putpixel(buf, a->x, a->y, getpixel(bg, a->x, a->y));
 2341:    *             a++;
 2342:    *         }
 2343:    *     }
 2344:          
 2345:          
 2346:          
 2347:          
 2348:          //Homeostasis:
 2349:          
 2350:          
 2351:                  /*
 2352:                  if(time(&timenow) - timestart >= 1) {
 2353:                      textprintf(buf, font, 10, 20, white, "Framerate: %i", frame);
 2354:                      textprintf(buf, font, 10, 30, white, "Comp rate: %i", compframe);
 2355:                      textprintf(buf, font, 10, 40, white, "Compframes: %i", COMPFRAMES);
 2356:                      if(frame < 20) {
 2357:                          COMPFRAMES -= 20 - frame;
 2358:                      }
 2359:                      else if(frame < COMPFRAMES) {
 2360:                          COMPFRAMES -= 3;
 2361:                      }
 2362:                      if(frame > 30) {
 2363:                          COMPFRAMES += (frame - 30) / 2;
 2364:                      }
 2365:                      if(COMPFRAMES < 1) COMPFRAMES = 1;
 2366:                      frame = 0;
 2367:                      compframe = 0;
 2368:                      timestart = time(&timenow);
 2369:                  }
 2370:                  if(compframe % COMPFRAMES == 0) {
 2371:                      drawatoms();
 2372:                      blit(buf, screen, 0, 0, 0, 0, 800, 600);
 2373:                      eraseatoms();
 2374:                      frame++;
 2375:                  }
 2375:                  */
